~ubuntu-branches/ubuntu/natty/mesa/natty-proposed

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Robert Hooker, Robert Hooker, Christopher James Halse Rogers
  • Date: 2010-09-14 08:55:40 UTC
  • mfrom: (1.2.28 upstream)
  • Revision ID: james.westby@ubuntu.com-20100914085540-m4fpl0hdjlfd4jgz
Tags: 7.9~git20100909-0ubuntu1
[ Robert Hooker ]
* New upstream git snapshot up to commit 94118fe2d4b1e5 (LP: #631413)
* New features include ATI HD5xxx series support in r600, and a vastly
  improved glsl compiler.
* Remove pre-generated .pc's, use the ones generated at build time
  instead.
* Remove all references to mesa-utils now that its no longer shipped
  with the mesa source.
* Disable the experimental ARB_fragment_shader option by default on
  i915, it exposes incomplete functionality that breaks KDE compositing
  among other things. It can be enabled via driconf still. (LP: #628930).

[ Christopher James Halse Rogers ]
* debian/patches/04_osmesa_version.diff:
  - Refresh for new upstream
* Bugs fixed in this release:
  - Fixes severe rendering corruption in Unity on radeon (LP: #628727,
    LP: #596292, LP: #599741, LP: #630315, LP: #613694, LP: #599741).
  - Also fixes rendering in gnome-shell (LP: #578619).
  - Flickering in OpenGL apps on radeon (LP: #626943, LP: #610541).
  - Provides preliminary support for new intel chips (LP: #601052).
* debian/rules:
  - Update configure flags to match upstream reshuffling.
  - Explicitly remove gallium DRI drivers that we don't want to ship.
* Update debian/gbp.conf for this Maverick-specific packaging
* libegl1-mesa-dri-x11,kms: There are no longer separate kms or x11 drivers
  for EGL, libegl1-mesa-drivers now contains a single driver that provides
  both backends.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
 
3
 *
 
4
 * Permission is hereby granted, free of charge, to any person obtaining a
 
5
 * copy of this software and associated documentation files (the "Software"),
 
6
 * to deal in the Software without restriction, including without limitation
 
7
 * on the rights to use, copy, modify, merge, publish, distribute, sub
 
8
 * license, and/or sell copies of the Software, and to permit persons to whom
 
9
 * the Software is furnished to do so, subject to the following conditions:
 
10
 *
 
11
 * The above copyright notice and this permission notice (including the next
 
12
 * paragraph) shall be included in all copies or substantial portions of the
 
13
 * Software.
 
14
 *
 
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 
18
 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
 
19
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 
20
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 
21
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
 
22
 *
 
23
 * Authors:
 
24
 *      Jerome Glisse
 
25
 *      Corbin Simpson <MostAwesomeDude@gmail.com>
 
26
 */
 
27
#include <pipe/p_screen.h>
 
28
#include <util/u_format.h>
 
29
#include <util/u_math.h>
 
30
#include <util/u_inlines.h>
 
31
#include <util/u_memory.h>
 
32
#include "state_tracker/drm_driver.h"
 
33
#include "r600_screen.h"
 
34
#include "r600_context.h"
 
35
#include "r600_resource.h"
 
36
 
 
37
extern struct u_resource_vtbl r600_buffer_vtbl;
 
38
 
 
39
u32 r600_domain_from_usage(unsigned usage)
 
40
{
 
41
        u32 domain = RADEON_GEM_DOMAIN_GTT;
 
42
 
 
43
        if (usage & PIPE_BIND_RENDER_TARGET) {
 
44
            domain |= RADEON_GEM_DOMAIN_VRAM;
 
45
        }
 
46
        if (usage & PIPE_BIND_DEPTH_STENCIL) {
 
47
            domain |= RADEON_GEM_DOMAIN_VRAM;
 
48
        }
 
49
        if (usage & PIPE_BIND_SAMPLER_VIEW) {
 
50
            domain |= RADEON_GEM_DOMAIN_VRAM;
 
51
        }
 
52
        /* also need BIND_BLIT_SOURCE/DESTINATION ? */
 
53
        if (usage & PIPE_BIND_VERTEX_BUFFER) {
 
54
            domain |= RADEON_GEM_DOMAIN_GTT;
 
55
        }
 
56
        if (usage & PIPE_BIND_INDEX_BUFFER) {
 
57
            domain |= RADEON_GEM_DOMAIN_GTT;
 
58
        }
 
59
        if (usage & PIPE_BIND_CONSTANT_BUFFER) {
 
60
            domain |= RADEON_GEM_DOMAIN_VRAM;
 
61
        }
 
62
 
 
63
        return domain;
 
64
}
 
65
 
 
66
struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
 
67
                                         const struct pipe_resource *templ)
 
68
{
 
69
        struct r600_screen *rscreen = r600_screen(screen);
 
70
        struct r600_resource *rbuffer;
 
71
        struct radeon_bo *bo;
 
72
        struct pb_desc desc;
 
73
        /* XXX We probably want a different alignment for buffers and textures. */
 
74
        unsigned alignment = 4096;
 
75
 
 
76
        rbuffer = CALLOC_STRUCT(r600_resource);
 
77
        if (rbuffer == NULL)
 
78
                return NULL;
 
79
 
 
80
        rbuffer->base.b = *templ;
 
81
        pipe_reference_init(&rbuffer->base.b.reference, 1);
 
82
        rbuffer->base.b.screen = screen;
 
83
        rbuffer->base.vtbl = &r600_buffer_vtbl;
 
84
 
 
85
        if ((rscreen->use_mem_constant == FALSE) && (rbuffer->base.b.bind & PIPE_BIND_CONSTANT_BUFFER)) {
 
86
                desc.alignment = alignment;
 
87
                desc.usage = rbuffer->base.b.bind;
 
88
                rbuffer->pb = pb_malloc_buffer_create(rbuffer->base.b.width0,
 
89
                                                      &desc);
 
90
                if (rbuffer->pb == NULL) {
 
91
                        free(rbuffer);
 
92
                        return NULL;
 
93
                }
 
94
                return &rbuffer->base.b;
 
95
        }
 
96
        rbuffer->domain = r600_domain_from_usage(rbuffer->base.b.bind);
 
97
        bo = radeon_bo(rscreen->rw, 0, rbuffer->base.b.width0, alignment, NULL);
 
98
        if (bo == NULL) {
 
99
                FREE(rbuffer);
 
100
                return NULL;
 
101
        }
 
102
        rbuffer->bo = bo;
 
103
        return &rbuffer->base.b;
 
104
}
 
105
 
 
106
struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen,
 
107
                                              void *ptr, unsigned bytes,
 
108
                                              unsigned bind)
 
109
{
 
110
        struct r600_resource *rbuffer;
 
111
        struct r600_screen *rscreen = r600_screen(screen);
 
112
        struct pipe_resource templ;
 
113
 
 
114
        memset(&templ, 0, sizeof(struct pipe_resource));
 
115
        templ.target = PIPE_BUFFER;
 
116
        templ.format = PIPE_FORMAT_R8_UNORM;
 
117
        templ.usage = PIPE_USAGE_IMMUTABLE;
 
118
        templ.bind = bind;
 
119
        templ.width0 = bytes;
 
120
        templ.height0 = 1;
 
121
        templ.depth0 = 1;
 
122
 
 
123
        rbuffer = (struct r600_resource*)r600_buffer_create(screen, &templ);
 
124
        if (rbuffer == NULL) {
 
125
                return NULL;
 
126
        }
 
127
        radeon_bo_map(rscreen->rw, rbuffer->bo);
 
128
        memcpy(rbuffer->bo->data, ptr, bytes);
 
129
        radeon_bo_unmap(rscreen->rw, rbuffer->bo);
 
130
        return &rbuffer->base.b;
 
131
}
 
132
 
 
133
static void r600_buffer_destroy(struct pipe_screen *screen,
 
134
                                struct pipe_resource *buf)
 
135
{
 
136
        struct r600_resource *rbuffer = (struct r600_resource*)buf;
 
137
        struct r600_screen *rscreen = r600_screen(screen);
 
138
 
 
139
        if (rbuffer->pb) {
 
140
                pipe_reference_init(&rbuffer->pb->base.reference, 0);
 
141
                pb_destroy(rbuffer->pb);
 
142
                rbuffer->pb = NULL;
 
143
        }
 
144
        if (rbuffer->bo) {
 
145
                radeon_bo_decref(rscreen->rw, rbuffer->bo);
 
146
        }
 
147
        memset(rbuffer, 0, sizeof(struct r600_resource));
 
148
        FREE(rbuffer);
 
149
}
 
150
 
 
151
static void *r600_buffer_transfer_map(struct pipe_context *pipe,
 
152
                                      struct pipe_transfer *transfer)
 
153
{
 
154
        struct r600_resource *rbuffer = (struct r600_resource*)transfer->resource;
 
155
        struct r600_screen *rscreen = r600_screen(pipe->screen);
 
156
        int write = 0;
 
157
 
 
158
        if (rbuffer->pb) {
 
159
                return (uint8_t*)pb_map(rbuffer->pb, transfer->usage) + transfer->box.x;
 
160
        }
 
161
        if (transfer->usage & PIPE_TRANSFER_DONTBLOCK) {
 
162
                /* FIXME */
 
163
        }
 
164
        if (transfer->usage & PIPE_TRANSFER_WRITE) {
 
165
                write = 1;
 
166
        }
 
167
        if (radeon_bo_map(rscreen->rw, rbuffer->bo)) {
 
168
                return NULL;
 
169
        }
 
170
        return (uint8_t*)rbuffer->bo->data + transfer->box.x;
 
171
}
 
172
 
 
173
static void r600_buffer_transfer_unmap(struct pipe_context *pipe,
 
174
                                        struct pipe_transfer *transfer)
 
175
{
 
176
        struct r600_resource *rbuffer = (struct r600_resource*)transfer->resource;
 
177
        struct r600_screen *rscreen = r600_screen(pipe->screen);
 
178
 
 
179
        if (rbuffer->pb) {
 
180
                pb_unmap(rbuffer->pb);
 
181
        } else {
 
182
                radeon_bo_unmap(rscreen->rw, rbuffer->bo);
 
183
        }
 
184
}
 
185
 
 
186
static void r600_buffer_transfer_flush_region(struct pipe_context *pipe,
 
187
                                              struct pipe_transfer *transfer,
 
188
                                              const struct pipe_box *box)
 
189
{
 
190
}
 
191
 
 
192
unsigned r600_buffer_is_referenced_by_cs(struct pipe_context *context,
 
193
                                         struct pipe_resource *buf,
 
194
                                         unsigned face, unsigned level)
 
195
{
 
196
        /* FIXME */
 
197
        return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
 
198
}
 
199
 
 
200
struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen,
 
201
                                              struct winsys_handle *whandle)
 
202
{
 
203
        struct radeon *rw = (struct radeon*)screen->winsys;
 
204
        struct r600_resource *rbuffer;
 
205
        struct radeon_bo *bo = NULL;
 
206
 
 
207
        bo = radeon_bo(rw, whandle->handle, 0, 0, NULL);
 
208
        if (bo == NULL) {
 
209
                return NULL;
 
210
        }
 
211
 
 
212
        rbuffer = CALLOC_STRUCT(r600_resource);
 
213
        if (rbuffer == NULL) {
 
214
                radeon_bo_decref(rw, bo);
 
215
                return NULL;
 
216
        }
 
217
 
 
218
        pipe_reference_init(&rbuffer->base.b.reference, 1);
 
219
        rbuffer->base.b.target = PIPE_BUFFER;
 
220
        rbuffer->base.b.screen = screen;
 
221
        rbuffer->base.vtbl = &r600_buffer_vtbl;
 
222
        rbuffer->bo = bo;
 
223
        return &rbuffer->base.b;
 
224
}
 
225
 
 
226
struct u_resource_vtbl r600_buffer_vtbl =
 
227
{
 
228
        u_default_resource_get_handle,          /* get_handle */
 
229
        r600_buffer_destroy,                    /* resource_destroy */
 
230
        r600_buffer_is_referenced_by_cs,        /* is_buffer_referenced */
 
231
        u_default_get_transfer,                 /* get_transfer */
 
232
        u_default_transfer_destroy,             /* transfer_destroy */
 
233
        r600_buffer_transfer_map,               /* transfer_map */
 
234
        r600_buffer_transfer_flush_region,      /* transfer_flush_region */
 
235
        r600_buffer_transfer_unmap,             /* transfer_unmap */
 
236
        u_default_transfer_inline_write         /* transfer_inline_write */
 
237
};