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

« back to all changes in this revision

Viewing changes to src/gallium/drivers/nouveau/nv04_surface_2d.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
 
#include "pipe/p_context.h"
2
 
#include "pipe/p_format.h"
3
 
#include "util/u_format.h"
4
 
#include "util/u_math.h"
5
 
#include "util/u_memory.h"
6
 
 
7
 
#include "nouveau/nouveau_winsys.h"
8
 
#include "nouveau/nouveau_util.h"
9
 
#include "nouveau/nouveau_screen.h"
10
 
#include "nv04_surface_2d.h"
11
 
 
12
 
static INLINE int
13
 
nv04_surface_format(enum pipe_format format)
14
 
{
15
 
        switch (format) {
16
 
        case PIPE_FORMAT_A8_UNORM:
17
 
        case PIPE_FORMAT_L8_UNORM:
18
 
        case PIPE_FORMAT_I8_UNORM:
19
 
                return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;
20
 
        case PIPE_FORMAT_R16_SNORM:
21
 
        case PIPE_FORMAT_B5G6R5_UNORM:
22
 
        case PIPE_FORMAT_Z16_UNORM:
23
 
        case PIPE_FORMAT_L8A8_UNORM:
24
 
                return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5;
25
 
        case PIPE_FORMAT_B8G8R8X8_UNORM:
26
 
        case PIPE_FORMAT_B8G8R8A8_UNORM:
27
 
                return NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8;
28
 
        case PIPE_FORMAT_S8Z24_UNORM:
29
 
        case PIPE_FORMAT_X8Z24_UNORM:
30
 
                return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32;
31
 
        default:
32
 
                return -1;
33
 
        }
34
 
}
35
 
 
36
 
static INLINE int
37
 
nv04_rect_format(enum pipe_format format)
38
 
{
39
 
        switch (format) {
40
 
        case PIPE_FORMAT_A8_UNORM:
41
 
                return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8;
42
 
        case PIPE_FORMAT_B5G6R5_UNORM:
43
 
        case PIPE_FORMAT_L8A8_UNORM:
44
 
        case PIPE_FORMAT_Z16_UNORM:
45
 
                return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5;
46
 
        case PIPE_FORMAT_B8G8R8X8_UNORM:
47
 
        case PIPE_FORMAT_B8G8R8A8_UNORM:
48
 
        case PIPE_FORMAT_S8Z24_UNORM:
49
 
        case PIPE_FORMAT_X8Z24_UNORM:
50
 
                return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8;
51
 
        default:
52
 
                return -1;
53
 
        }
54
 
}
55
 
 
56
 
static INLINE int
57
 
nv04_scaled_image_format(enum pipe_format format)
58
 
{
59
 
        switch (format) {
60
 
        case PIPE_FORMAT_A8_UNORM:
61
 
        case PIPE_FORMAT_L8_UNORM:
62
 
        case PIPE_FORMAT_I8_UNORM:
63
 
                return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_Y8;
64
 
        case PIPE_FORMAT_B5G5R5A1_UNORM:
65
 
                return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A1R5G5B5;
66
 
        case PIPE_FORMAT_B8G8R8A8_UNORM:
67
 
                return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8;
68
 
        case PIPE_FORMAT_B8G8R8X8_UNORM:
69
 
                return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_X8R8G8B8;
70
 
        case PIPE_FORMAT_B5G6R5_UNORM:
71
 
        case PIPE_FORMAT_R16_SNORM:
72
 
        case PIPE_FORMAT_L8A8_UNORM:
73
 
                return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_R5G6B5;
74
 
        default:
75
 
                return -1;
76
 
        }
77
 
}
78
 
 
79
 
static INLINE unsigned
80
 
nv04_swizzle_bits_square(unsigned x, unsigned y)
81
 
{
82
 
        unsigned u = (x & 0x001) << 0 |
83
 
                     (x & 0x002) << 1 |
84
 
                     (x & 0x004) << 2 |
85
 
                     (x & 0x008) << 3 |
86
 
                     (x & 0x010) << 4 |
87
 
                     (x & 0x020) << 5 |
88
 
                     (x & 0x040) << 6 |
89
 
                     (x & 0x080) << 7 |
90
 
                     (x & 0x100) << 8 |
91
 
                     (x & 0x200) << 9 |
92
 
                     (x & 0x400) << 10 |
93
 
                     (x & 0x800) << 11;
94
 
 
95
 
        unsigned v = (y & 0x001) << 1 |
96
 
                     (y & 0x002) << 2 |
97
 
                     (y & 0x004) << 3 |
98
 
                     (y & 0x008) << 4 |
99
 
                     (y & 0x010) << 5 |
100
 
                     (y & 0x020) << 6 |
101
 
                     (y & 0x040) << 7 |
102
 
                     (y & 0x080) << 8 |
103
 
                     (y & 0x100) << 9 |
104
 
                     (y & 0x200) << 10 |
105
 
                     (y & 0x400) << 11 |
106
 
                     (y & 0x800) << 12;
107
 
        return v | u;
108
 
}
109
 
 
110
 
/* rectangular swizzled textures are linear concatenations of swizzled square tiles */
111
 
static INLINE unsigned
112
 
nv04_swizzle_bits(unsigned x, unsigned y, unsigned w, unsigned h)
113
 
{
114
 
        unsigned s = MIN2(w, h);
115
 
        unsigned m = s - 1;
116
 
        return (((x | y) & ~m) * s) | nv04_swizzle_bits_square(x & m, y & m);
117
 
}
118
 
 
119
 
static int
120
 
nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx,
121
 
                          struct pipe_surface *dst, int dx, int dy,
122
 
                          struct pipe_surface *src, int sx, int sy,
123
 
                          int w, int h)
124
 
{
125
 
        struct nouveau_channel *chan = ctx->swzsurf->channel;
126
 
        struct nouveau_grobj *swzsurf = ctx->swzsurf;
127
 
        struct nouveau_grobj *sifm = ctx->sifm;
128
 
        struct nouveau_bo *src_bo = nouveau_bo(ctx->buf(src));
129
 
        struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst));
130
 
        const unsigned src_pitch = ((struct nv04_surface *)src)->pitch;
131
 
        /* Max width & height may not be the same on all HW, but must be POT */
132
 
        const unsigned max_w = 1024;
133
 
        const unsigned max_h = 1024;
134
 
        unsigned sub_w = w > max_w ? max_w : w;
135
 
        unsigned sub_h = h > max_h ? max_h : h;
136
 
        unsigned x;
137
 
        unsigned y;
138
 
 
139
 
        /* Swizzled surfaces must be POT  */
140
 
        assert(util_is_pot(dst->width) && util_is_pot(dst->height));
141
 
 
142
 
        /* If area is too large to copy in one shot we must copy it in POT chunks to meet alignment requirements */
143
 
        assert(sub_w == w || util_is_pot(sub_w));
144
 
        assert(sub_h == h || util_is_pot(sub_h));
145
 
 
146
 
        MARK_RING (chan, 8 + ((w+sub_w)/sub_w)*((h+sub_h)/sub_h)*17, 2 +
147
 
                         ((w+sub_w)/sub_w)*((h+sub_h)/sub_h)*2);
148
 
 
149
 
        BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1);
150
 
        OUT_RELOCo(chan, dst_bo,
151
 
                         NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
152
 
 
153
 
        BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_FORMAT, 1);
154
 
        OUT_RING  (chan, nv04_surface_format(dst->format) |
155
 
                         log2i(dst->width) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_U_SHIFT |
156
 
                         log2i(dst->height) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_SHIFT);
157
 
 
158
 
        BEGIN_RING(chan, sifm, NV03_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1);
159
 
        OUT_RELOCo(chan, src_bo,
160
 
                         NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
161
 
        BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1);
162
 
        OUT_RING  (chan, swzsurf->handle);
163
 
 
164
 
        for (y = 0; y < h; y += sub_h) {
165
 
          sub_h = MIN2(sub_h, h - y);
166
 
 
167
 
          for (x = 0; x < w; x += sub_w) {
168
 
            sub_w = MIN2(sub_w, w - x);
169
 
 
170
 
            assert(!(dst->offset & 63));
171
 
 
172
 
            BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_OFFSET, 1);
173
 
            OUT_RELOCl(chan, dst_bo, dst->offset,
174
 
                             NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
175
 
 
176
 
            BEGIN_RING(chan, sifm, NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 9);
177
 
            OUT_RING  (chan, NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE);
178
 
            OUT_RING  (chan, nv04_scaled_image_format(src->format));
179
 
            OUT_RING  (chan, NV03_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY);
180
 
            OUT_RING  (chan, (x + dx) | ((y + dy) << NV03_SCALED_IMAGE_FROM_MEMORY_CLIP_POINT_Y_SHIFT));
181
 
            OUT_RING  (chan, sub_h << NV03_SCALED_IMAGE_FROM_MEMORY_CLIP_SIZE_H_SHIFT | sub_w);
182
 
            OUT_RING  (chan, (x + dx) | ((y + dy) << NV03_SCALED_IMAGE_FROM_MEMORY_OUT_POINT_Y_SHIFT));
183
 
            OUT_RING  (chan, sub_h << NV03_SCALED_IMAGE_FROM_MEMORY_OUT_SIZE_H_SHIFT | sub_w);
184
 
            OUT_RING  (chan, 1 << 20);
185
 
            OUT_RING  (chan, 1 << 20);
186
 
 
187
 
            BEGIN_RING(chan, sifm, NV03_SCALED_IMAGE_FROM_MEMORY_SIZE, 4);
188
 
            OUT_RING  (chan, sub_h << NV03_SCALED_IMAGE_FROM_MEMORY_SIZE_H_SHIFT | sub_w);
189
 
            OUT_RING  (chan, src_pitch |
190
 
                             NV03_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER |
191
 
                             NV03_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE);
192
 
            OUT_RELOCl(chan, src_bo, src->offset + (sy+y) * src_pitch + (sx+x) * util_format_get_blocksize(src->texture->format),
193
 
                             NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
194
 
            OUT_RING  (chan, 0);
195
 
          }
196
 
        }
197
 
 
198
 
        return 0;
199
 
}
200
 
 
201
 
static int
202
 
nv04_surface_copy_m2mf(struct nv04_surface_2d *ctx,
203
 
                       struct pipe_surface *dst, int dx, int dy,
204
 
                       struct pipe_surface *src, int sx, int sy, int w, int h)
205
 
{
206
 
        struct nouveau_channel *chan = ctx->m2mf->channel;
207
 
        struct nouveau_grobj *m2mf = ctx->m2mf;
208
 
        struct nouveau_bo *src_bo = nouveau_bo(ctx->buf(src));
209
 
        struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst));
210
 
        unsigned src_pitch = ((struct nv04_surface *)src)->pitch;
211
 
        unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch;
212
 
        unsigned dst_offset = dst->offset + dy * dst_pitch +
213
 
                              dx * util_format_get_blocksize(dst->texture->format);
214
 
        unsigned src_offset = src->offset + sy * src_pitch +
215
 
                              sx * util_format_get_blocksize(src->texture->format);
216
 
 
217
 
        MARK_RING (chan, 3 + ((h / 2047) + 1) * 9, 2 + ((h / 2047) + 1) * 2);
218
 
        BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2);
219
 
        OUT_RELOCo(chan, src_bo,
220
 
                   NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
221
 
        OUT_RELOCo(chan, dst_bo,
222
 
                   NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
223
 
 
224
 
        while (h) {
225
 
                int count = (h > 2047) ? 2047 : h;
226
 
 
227
 
                BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
228
 
                OUT_RELOCl(chan, src_bo, src_offset,
229
 
                           NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
230
 
                OUT_RELOCl(chan, dst_bo, dst_offset,
231
 
                           NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR);
232
 
                OUT_RING  (chan, src_pitch);
233
 
                OUT_RING  (chan, dst_pitch);
234
 
                OUT_RING  (chan, w * util_format_get_blocksize(src->texture->format));
235
 
                OUT_RING  (chan, count);
236
 
                OUT_RING  (chan, 0x0101);
237
 
                OUT_RING  (chan, 0);
238
 
 
239
 
                h -= count;
240
 
                src_offset += src_pitch * count;
241
 
                dst_offset += dst_pitch * count;
242
 
        }
243
 
 
244
 
        return 0;
245
 
}
246
 
 
247
 
static int
248
 
nv04_surface_copy_blit(struct nv04_surface_2d *ctx, struct pipe_surface *dst,
249
 
                       int dx, int dy, struct pipe_surface *src, int sx, int sy,
250
 
                       int w, int h)
251
 
{
252
 
        struct nouveau_channel *chan = ctx->surf2d->channel;
253
 
        struct nouveau_grobj *surf2d = ctx->surf2d;
254
 
        struct nouveau_grobj *blit = ctx->blit;
255
 
        struct nouveau_bo *src_bo = nouveau_bo(ctx->buf(src));
256
 
        struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst));
257
 
        unsigned src_pitch = ((struct nv04_surface *)src)->pitch;
258
 
        unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch;
259
 
        int format;
260
 
 
261
 
        format = nv04_surface_format(dst->format);
262
 
        if (format < 0)
263
 
                return 1;
264
 
 
265
 
        MARK_RING (chan, 12, 4);
266
 
        BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
267
 
        OUT_RELOCo(chan, src_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
268
 
        OUT_RELOCo(chan, dst_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
269
 
        BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
270
 
        OUT_RING  (chan, format);
271
 
        OUT_RING  (chan, (dst_pitch << 16) | src_pitch);
272
 
        OUT_RELOCl(chan, src_bo, src->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
273
 
        OUT_RELOCl(chan, dst_bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
274
 
 
275
 
        BEGIN_RING(chan, blit, 0x0300, 3);
276
 
        OUT_RING  (chan, (sy << 16) | sx);
277
 
        OUT_RING  (chan, (dy << 16) | dx);
278
 
        OUT_RING  (chan, ( h << 16) |  w);
279
 
 
280
 
        return 0;
281
 
}
282
 
 
283
 
static void
284
 
nv04_surface_copy(struct nv04_surface_2d *ctx, struct pipe_surface *dst,
285
 
                  int dx, int dy, struct pipe_surface *src, int sx, int sy,
286
 
                  int w, int h)
287
 
{
288
 
        unsigned src_pitch = ((struct nv04_surface *)src)->pitch;
289
 
        unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch;
290
 
        int src_linear = src->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR;
291
 
        int dst_linear = dst->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR;
292
 
 
293
 
        assert(src->format == dst->format);
294
 
 
295
 
        /* Setup transfer to swizzle the texture to vram if needed */
296
 
        if (src_linear && !dst_linear && w > 1 && h > 1) {
297
 
           nv04_surface_copy_swizzle(ctx, dst, dx, dy, src, sx, sy, w, h);
298
 
           return;
299
 
        }
300
 
 
301
 
        /* NV_CONTEXT_SURFACES_2D has buffer alignment restrictions, fallback
302
 
         * to NV_MEMORY_TO_MEMORY_FORMAT in this case.
303
 
         */
304
 
        if ((src->offset & 63) || (dst->offset & 63) ||
305
 
            (src_pitch & 63) || (dst_pitch & 63)) {
306
 
                nv04_surface_copy_m2mf(ctx, dst, dx, dy, src, sx, sy, w, h);
307
 
                return;
308
 
        }
309
 
 
310
 
        nv04_surface_copy_blit(ctx, dst, dx, dy, src, sx, sy, w, h);
311
 
}
312
 
 
313
 
static void
314
 
nv04_surface_fill(struct nv04_surface_2d *ctx, struct pipe_surface *dst,
315
 
                  int dx, int dy, int w, int h, unsigned value)
316
 
{
317
 
        struct nouveau_channel *chan = ctx->surf2d->channel;
318
 
        struct nouveau_grobj *surf2d = ctx->surf2d;
319
 
        struct nouveau_grobj *rect = ctx->rect;
320
 
        struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst));
321
 
        unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch;
322
 
        int cs2d_format, gdirect_format;
323
 
 
324
 
        cs2d_format = nv04_surface_format(dst->format);
325
 
        assert(cs2d_format >= 0);
326
 
 
327
 
        gdirect_format = nv04_rect_format(dst->format);
328
 
        assert(gdirect_format >= 0);
329
 
 
330
 
        MARK_RING (chan, 16, 4);
331
 
        BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
332
 
        OUT_RELOCo(chan, dst_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
333
 
        OUT_RELOCo(chan, dst_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
334
 
        BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
335
 
        OUT_RING  (chan, cs2d_format);
336
 
        OUT_RING  (chan, (dst_pitch << 16) | dst_pitch);
337
 
        OUT_RELOCl(chan, dst_bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
338
 
        OUT_RELOCl(chan, dst_bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
339
 
 
340
 
        BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1);
341
 
        OUT_RING  (chan, gdirect_format);
342
 
        BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1);
343
 
        OUT_RING  (chan, value);
344
 
        BEGIN_RING(chan, rect,
345
 
                   NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2);
346
 
        OUT_RING  (chan, (dx << 16) | dy);
347
 
        OUT_RING  (chan, ( w << 16) |  h);
348
 
}
349
 
 
350
 
void
351
 
nv04_surface_2d_takedown(struct nv04_surface_2d **pctx)
352
 
{
353
 
        struct nv04_surface_2d *ctx;
354
 
 
355
 
        if (!pctx || !*pctx)
356
 
                return;
357
 
        ctx = *pctx;
358
 
        *pctx = NULL;
359
 
 
360
 
        nouveau_notifier_free(&ctx->ntfy);
361
 
        nouveau_grobj_free(&ctx->m2mf);
362
 
        nouveau_grobj_free(&ctx->surf2d);
363
 
        nouveau_grobj_free(&ctx->swzsurf);
364
 
        nouveau_grobj_free(&ctx->rect);
365
 
        nouveau_grobj_free(&ctx->blit);
366
 
        nouveau_grobj_free(&ctx->sifm);
367
 
 
368
 
        FREE(ctx);
369
 
}
370
 
 
371
 
struct nv04_surface_2d *
372
 
nv04_surface_2d_init(struct nouveau_screen *screen)
373
 
{
374
 
        struct nv04_surface_2d *ctx = CALLOC_STRUCT(nv04_surface_2d);
375
 
        struct nouveau_channel *chan = screen->channel;
376
 
        unsigned handle = 0x88000000, class;
377
 
        int ret;
378
 
 
379
 
        if (!ctx)
380
 
                return NULL;
381
 
 
382
 
        ret = nouveau_notifier_alloc(chan, handle++, 1, &ctx->ntfy);
383
 
        if (ret) {
384
 
                nv04_surface_2d_takedown(&ctx);
385
 
                return NULL;
386
 
        }
387
 
 
388
 
        ret = nouveau_grobj_alloc(chan, handle++, 0x0039, &ctx->m2mf);
389
 
        if (ret) {
390
 
                nv04_surface_2d_takedown(&ctx);
391
 
                return NULL;
392
 
        }
393
 
 
394
 
        BEGIN_RING(chan, ctx->m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
395
 
        OUT_RING  (chan, ctx->ntfy->handle);
396
 
 
397
 
        if (chan->device->chipset < 0x10)
398
 
                class = NV04_CONTEXT_SURFACES_2D;
399
 
        else
400
 
                class = NV10_CONTEXT_SURFACES_2D;
401
 
 
402
 
        ret = nouveau_grobj_alloc(chan, handle++, class, &ctx->surf2d);
403
 
        if (ret) {
404
 
                nv04_surface_2d_takedown(&ctx);
405
 
                return NULL;
406
 
        }
407
 
 
408
 
        BEGIN_RING(chan, ctx->surf2d,
409
 
                         NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
410
 
        OUT_RING  (chan, chan->vram->handle);
411
 
        OUT_RING  (chan, chan->vram->handle);
412
 
 
413
 
        if (chan->device->chipset < 0x10)
414
 
                class = NV04_IMAGE_BLIT;
415
 
        else
416
 
                class = NV12_IMAGE_BLIT;
417
 
 
418
 
        ret = nouveau_grobj_alloc(chan, handle++, class, &ctx->blit);
419
 
        if (ret) {
420
 
                nv04_surface_2d_takedown(&ctx);
421
 
                return NULL;
422
 
        }
423
 
 
424
 
        BEGIN_RING(chan, ctx->blit, NV01_IMAGE_BLIT_DMA_NOTIFY, 1);
425
 
        OUT_RING  (chan, ctx->ntfy->handle);
426
 
        BEGIN_RING(chan, ctx->blit, NV04_IMAGE_BLIT_SURFACE, 1);
427
 
        OUT_RING  (chan, ctx->surf2d->handle);
428
 
        BEGIN_RING(chan, ctx->blit, NV01_IMAGE_BLIT_OPERATION, 1);
429
 
        OUT_RING  (chan, NV01_IMAGE_BLIT_OPERATION_SRCCOPY);
430
 
 
431
 
        ret = nouveau_grobj_alloc(chan, handle++, NV04_GDI_RECTANGLE_TEXT,
432
 
                                  &ctx->rect);
433
 
        if (ret) {
434
 
                nv04_surface_2d_takedown(&ctx);
435
 
                return NULL;
436
 
        }
437
 
 
438
 
        BEGIN_RING(chan, ctx->rect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1);
439
 
        OUT_RING  (chan, ctx->ntfy->handle);
440
 
        BEGIN_RING(chan, ctx->rect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1);
441
 
        OUT_RING  (chan, ctx->surf2d->handle);
442
 
        BEGIN_RING(chan, ctx->rect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
443
 
        OUT_RING  (chan, NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY);
444
 
        BEGIN_RING(chan, ctx->rect,
445
 
                         NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1);
446
 
        OUT_RING  (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE);
447
 
 
448
 
        switch (chan->device->chipset & 0xf0) {
449
 
        case 0x00:
450
 
        case 0x10:
451
 
                class = NV04_SWIZZLED_SURFACE;
452
 
                break;
453
 
        case 0x20:
454
 
                class = NV20_SWIZZLED_SURFACE;
455
 
                break;
456
 
        case 0x30:
457
 
                class = NV30_SWIZZLED_SURFACE;
458
 
                break;
459
 
        case 0x40:
460
 
        case 0x60:
461
 
                class = NV40_SWIZZLED_SURFACE;
462
 
                break;
463
 
        default:
464
 
                /* Famous last words: this really can't happen.. */
465
 
                assert(0);
466
 
                break;
467
 
        }
468
 
 
469
 
        ret = nouveau_grobj_alloc(chan, handle++, class, &ctx->swzsurf);
470
 
        if (ret) {
471
 
                nv04_surface_2d_takedown(&ctx);
472
 
                return NULL;
473
 
        }
474
 
 
475
 
        switch (chan->device->chipset & 0xf0) {
476
 
        case 0x10:
477
 
        case 0x20:
478
 
                class = NV10_SCALED_IMAGE_FROM_MEMORY;
479
 
                break;
480
 
        case 0x30:
481
 
                class = NV30_SCALED_IMAGE_FROM_MEMORY;
482
 
                break;
483
 
        case 0x40:
484
 
        case 0x60:
485
 
                class = NV40_SCALED_IMAGE_FROM_MEMORY;
486
 
                break;
487
 
        default:
488
 
                class = NV04_SCALED_IMAGE_FROM_MEMORY;
489
 
                break;
490
 
        }
491
 
 
492
 
        ret = nouveau_grobj_alloc(chan, handle++, class, &ctx->sifm);
493
 
        if (ret) {
494
 
                nv04_surface_2d_takedown(&ctx);
495
 
                return NULL;
496
 
        }
497
 
 
498
 
        ctx->copy = nv04_surface_copy;
499
 
        ctx->fill = nv04_surface_fill;
500
 
        return ctx;
501
 
}
502
 
 
503
 
struct nv04_surface*
504
 
nv04_surface_wrap_for_render(struct pipe_screen *pscreen, struct nv04_surface_2d* eng2d, struct nv04_surface* ns)
505
 
{
506
 
        int temp_flags;
507
 
 
508
 
        // printf("creating temp, flags is %i!\n", flags);
509
 
 
510
 
        if(ns->base.usage & PIPE_BUFFER_USAGE_DISCARD)
511
 
        {
512
 
                temp_flags = ns->base.usage | PIPE_BUFFER_USAGE_GPU_READ;
513
 
                ns->base.usage = PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER | PIPE_BUFFER_USAGE_DISCARD;
514
 
        }
515
 
        else
516
 
        {
517
 
                temp_flags = ns->base.usage | PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE;
518
 
                ns->base.usage = PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER | PIPE_BUFFER_USAGE_GPU_READ;
519
 
        }
520
 
 
521
 
        struct nv40_screen* screen = (struct nv40_screen*)pscreen;
522
 
        ns->base.usage = PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE;
523
 
 
524
 
        struct pipe_texture templ;
525
 
        memset(&templ, 0, sizeof(templ));
526
 
        templ.format = ns->base.texture->format;
527
 
        templ.target = PIPE_TEXTURE_2D;
528
 
        templ.width0 = ns->base.width;
529
 
        templ.height0 = ns->base.height;
530
 
        templ.depth0 = 1;
531
 
        templ.last_level = 0;
532
 
 
533
 
        // TODO: this is probably wrong and we should specifically handle multisampling somehow once it is implemented
534
 
        templ.nr_samples = ns->base.texture->nr_samples;
535
 
 
536
 
        templ.tex_usage = ns->base.texture->tex_usage | PIPE_TEXTURE_USAGE_RENDER_TARGET;
537
 
 
538
 
        struct pipe_texture* temp_tex = pscreen->texture_create(pscreen, &templ);
539
 
        struct nv04_surface* temp_ns = (struct nv04_surface*)pscreen->get_tex_surface(pscreen, temp_tex, 0, 0, 0, temp_flags);
540
 
        temp_ns->backing = ns;
541
 
 
542
 
        if(ns->base.usage & PIPE_BUFFER_USAGE_GPU_READ)
543
 
                eng2d->copy(eng2d, &temp_ns->backing->base, 0, 0, &ns->base, 0, 0, ns->base.width, ns->base.height);
544
 
 
545
 
        return temp_ns;
546
 
}
547