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

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/r600/radeon_span.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:
1
 
/**************************************************************************
2
 
 
3
 
Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
4
 
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5
 
                     VA Linux Systems Inc., Fremont, California.
6
 
 
7
 
The Weather Channel (TM) funded Tungsten Graphics to develop the
8
 
initial release of the Radeon 8500 driver under the XFree86 license.
9
 
This notice must be preserved.
10
 
 
11
 
All Rights Reserved.
12
 
 
13
 
Permission is hereby granted, free of charge, to any person obtaining
14
 
a copy of this software and associated documentation files (the
15
 
"Software"), to deal in the Software without restriction, including
16
 
without limitation the rights to use, copy, modify, merge, publish,
17
 
distribute, sublicense, and/or sell copies of the Software, and to
18
 
permit persons to whom the Software is furnished to do so, subject to
19
 
the following conditions:
20
 
 
21
 
The above copyright notice and this permission notice (including the
22
 
next paragraph) shall be included in all copies or substantial
23
 
portions of the Software.
24
 
 
25
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26
 
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27
 
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
28
 
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
29
 
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30
 
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31
 
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32
 
 
33
 
**************************************************************************/
34
 
 
35
 
/*
36
 
 * Authors:
37
 
 *   Kevin E. Martin <martin@valinux.com>
38
 
 *   Gareth Hughes <gareth@valinux.com>
39
 
 *   Keith Whitwell <keith@tungstengraphics.com>
40
 
 *
41
 
 */
42
 
 
43
 
#include "main/glheader.h"
44
 
#include "main/texformat.h"
45
 
#include "swrast/swrast.h"
46
 
 
47
 
#include "radeon_common.h"
48
 
#include "radeon_lock.h"
49
 
#include "radeon_span.h"
50
 
 
51
 
#define DBG 0
52
 
 
53
 
#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
54
 
#if defined(__linux__)
55
 
#include <byteswap.h>
56
 
#define CPU_TO_LE16( x )        bswap_16( x )
57
 
#define LE16_TO_CPU( x )        bswap_16( x )
58
 
#endif /* __linux__ */
59
 
#else
60
 
#define CPU_TO_LE16( x )        ( x )
61
 
#define LE16_TO_CPU( x )        ( x )
62
 
#endif
63
 
 
64
 
static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb);
65
 
 
66
 
 
67
 
/* r200 depth buffer is always tiled - this is the formula
68
 
   according to the docs unless I typo'ed in it
69
 
*/
70
 
#if defined(RADEON_R200)
71
 
static GLubyte *r200_depth_2byte(const struct radeon_renderbuffer * rrb,
72
 
                                 GLint x, GLint y)
73
 
{
74
 
    GLubyte *ptr = rrb->bo->ptr + rrb->draw_offset;
75
 
    GLint offset;
76
 
    if (rrb->has_surface) {
77
 
        offset = x * rrb->cpp + y * rrb->pitch;
78
 
    } else {
79
 
        GLuint b;
80
 
        offset = 0;
81
 
        b = (((y  >> 4) * (rrb->pitch >> 8) + (x >> 6)));
82
 
        offset += (b >> 1) << 12;
83
 
        offset += (((rrb->pitch >> 8) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11;
84
 
        offset += ((y >> 2) & 0x3) << 9;
85
 
        offset += ((x >> 3) & 0x1) << 8;
86
 
        offset += ((x >> 4) & 0x3) << 6;
87
 
        offset += ((x >> 2) & 0x1) << 5;
88
 
        offset += ((y >> 1) & 0x1) << 4;
89
 
        offset += ((x >> 1) & 0x1) << 3;
90
 
        offset += (y & 0x1) << 2;
91
 
        offset += (x & 0x1) << 1;
92
 
    }
93
 
    return &ptr[offset];
94
 
}
95
 
 
96
 
static GLubyte *r200_depth_4byte(const struct radeon_renderbuffer * rrb,
97
 
                                 GLint x, GLint y)
98
 
{
99
 
    GLubyte *ptr = rrb->bo->ptr + rrb->draw_offset;
100
 
    GLint offset;
101
 
    if (rrb->has_surface) {
102
 
        offset = x * rrb->cpp + y * rrb->pitch;
103
 
    } else {
104
 
        GLuint b;
105
 
        offset = 0;
106
 
        b = (((y & 0x7ff) >> 4) * (rrb->pitch >> 7) + (x >> 5));
107
 
        offset += (b >> 1) << 12;
108
 
        offset += (((rrb->pitch >> 7) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11;
109
 
        offset += ((y >> 2) & 0x3) << 9;
110
 
        offset += ((x >> 2) & 0x1) << 8;
111
 
        offset += ((x >> 3) & 0x3) << 6;
112
 
        offset += ((y >> 1) & 0x1) << 5;
113
 
        offset += ((x >> 1) & 0x1) << 4;
114
 
        offset += (y & 0x1) << 3;
115
 
        offset += (x & 0x1) << 2;
116
 
    }
117
 
    return &ptr[offset];
118
 
}
119
 
#endif
120
 
 
121
 
/* r600 tiling
122
 
 * two main types:
123
 
 * - 1D (akin to macro-linear/micro-tiled on older asics)
124
 
 * - 2D (akin to macro-tiled/micro-tiled on older asics)
125
 
 */
126
 
#if defined(RADEON_R600)
127
 
static inline GLint r600_1d_tile_helper(const struct radeon_renderbuffer * rrb,
128
 
                                        GLint x, GLint y, GLint is_depth, GLint is_stencil)
129
 
{
130
 
    GLint element_bytes = rrb->cpp;
131
 
    GLint num_samples = 1;
132
 
    GLint tile_width = 8;
133
 
    GLint tile_height = 8;
134
 
    GLint tile_thickness = 1;
135
 
    GLint pitch_elements = rrb->pitch / element_bytes;
136
 
    GLint height = rrb->base.Height;
137
 
    GLint z = 0;
138
 
    GLint sample_number = 0;
139
 
    /* */
140
 
    GLint tile_bytes;
141
 
    GLint tiles_per_row;
142
 
    GLint tiles_per_slice;
143
 
    GLint slice_offset;
144
 
    GLint tile_row_index;
145
 
    GLint tile_column_index;
146
 
    GLint tile_offset;
147
 
    GLint pixel_number = 0;
148
 
    GLint element_offset;
149
 
    GLint offset = 0;
150
 
 
151
 
    tile_bytes = tile_width * tile_height * tile_thickness * element_bytes * num_samples;
152
 
    tiles_per_row = pitch_elements / tile_width;
153
 
    tiles_per_slice = tiles_per_row * (height / tile_height);
154
 
    slice_offset = (z / tile_thickness) * tiles_per_slice * tile_bytes;
155
 
    tile_row_index = y / tile_height;
156
 
    tile_column_index = x / tile_width;
157
 
    tile_offset = ((tile_row_index * tiles_per_row) + tile_column_index) * tile_bytes;
158
 
 
159
 
    if (is_depth) {
160
 
            GLint pixel_offset = 0;
161
 
 
162
 
            pixel_number |= ((x >> 0) & 1) << 0; // pn[0] = x[0]
163
 
            pixel_number |= ((y >> 0) & 1) << 1; // pn[1] = y[0]
164
 
            pixel_number |= ((x >> 1) & 1) << 2; // pn[2] = x[1]
165
 
            pixel_number |= ((y >> 1) & 1) << 3; // pn[3] = y[1]
166
 
            pixel_number |= ((x >> 2) & 1) << 4; // pn[4] = x[2]
167
 
            pixel_number |= ((y >> 2) & 1) << 5; // pn[5] = y[2]
168
 
            switch (element_bytes) {
169
 
            case 2:
170
 
                    pixel_offset = pixel_number * element_bytes * num_samples;
171
 
                    break;
172
 
            case 4:
173
 
                    /* stencil and depth data are stored separately within a tile.
174
 
                     * stencil is stored in a contiguous tile before the depth tile.
175
 
                     * stencil element is 1 byte, depth element is 3 bytes.
176
 
                     * stencil tile is 64 bytes.
177
 
                     */
178
 
                    if (is_stencil)
179
 
                            pixel_offset = pixel_number * 1 * num_samples;
180
 
                    else
181
 
                            pixel_offset = (pixel_number * 3 * num_samples) + 64;
182
 
                    break;
183
 
            }
184
 
            element_offset = pixel_offset + (sample_number * element_bytes);
185
 
    } else {
186
 
            GLint sample_offset;
187
 
 
188
 
            switch (element_bytes) {
189
 
            case 1:
190
 
                    pixel_number |= ((x >> 0) & 1) << 0; // pn[0] = x[0]
191
 
                    pixel_number |= ((x >> 1) & 1) << 1; // pn[1] = x[1]
192
 
                    pixel_number |= ((x >> 2) & 1) << 2; // pn[2] = x[2]
193
 
                    pixel_number |= ((y >> 1) & 1) << 3; // pn[3] = y[1]
194
 
                    pixel_number |= ((y >> 0) & 1) << 4; // pn[4] = y[0]
195
 
                    pixel_number |= ((y >> 2) & 1) << 5; // pn[5] = y[2]
196
 
                    break;
197
 
            case 2:
198
 
                    pixel_number |= ((x >> 0) & 1) << 0; // pn[0] = x[0]
199
 
                    pixel_number |= ((x >> 1) & 1) << 1; // pn[1] = x[1]
200
 
                    pixel_number |= ((x >> 2) & 1) << 2; // pn[2] = x[2]
201
 
                    pixel_number |= ((y >> 0) & 1) << 3; // pn[3] = y[0]
202
 
                    pixel_number |= ((y >> 1) & 1) << 4; // pn[4] = y[1]
203
 
                    pixel_number |= ((y >> 2) & 1) << 5; // pn[5] = y[2]
204
 
                    break;
205
 
            case 4:
206
 
                    pixel_number |= ((x >> 0) & 1) << 0; // pn[0] = x[0]
207
 
                    pixel_number |= ((x >> 1) & 1) << 1; // pn[1] = x[1]
208
 
                    pixel_number |= ((y >> 0) & 1) << 2; // pn[2] = y[0]
209
 
                    pixel_number |= ((x >> 2) & 1) << 3; // pn[3] = x[2]
210
 
                    pixel_number |= ((y >> 1) & 1) << 4; // pn[4] = y[1]
211
 
                    pixel_number |= ((y >> 2) & 1) << 5; // pn[5] = y[2]
212
 
                    break;
213
 
            }
214
 
            sample_offset = sample_number * (tile_bytes / num_samples);
215
 
            element_offset = sample_offset + (pixel_number * element_bytes);
216
 
    }
217
 
    offset = slice_offset + tile_offset + element_offset;
218
 
    return offset;
219
 
}
220
 
 
221
 
static inline GLint r600_log2(GLint n)
222
 
{
223
 
        GLint log2 = 0;
224
 
 
225
 
        while (n >>= 1)
226
 
                ++log2;
227
 
        return log2;
228
 
}
229
 
 
230
 
static inline GLint r600_2d_tile_helper(const struct radeon_renderbuffer * rrb,
231
 
                                        GLint x, GLint y, GLint is_depth, GLint is_stencil)
232
 
{
233
 
        GLint group_bytes = rrb->group_bytes;
234
 
        GLint num_channels = rrb->num_channels;
235
 
        GLint num_banks = rrb->num_banks;
236
 
        GLint r7xx_bank_op = rrb->r7xx_bank_op;
237
 
        /* */
238
 
        GLint group_bits = r600_log2(group_bytes);
239
 
        GLint channel_bits = r600_log2(num_channels);
240
 
        GLint bank_bits = r600_log2(num_banks);
241
 
        GLint element_bytes = rrb->cpp;
242
 
        GLint num_samples = 1;
243
 
        GLint tile_width = 8;
244
 
        GLint tile_height = 8;
245
 
        GLint tile_thickness = 1;
246
 
        GLint macro_tile_width = num_banks;
247
 
        GLint macro_tile_height = num_channels;
248
 
        GLint pitch_elements = (rrb->pitch / element_bytes) / tile_width;
249
 
        GLint height = rrb->base.Height / tile_height;
250
 
        GLint z = 0;
251
 
        GLint sample_number = 0;
252
 
        /* */
253
 
        GLint tile_bytes;
254
 
        GLint macro_tile_bytes;
255
 
        GLint macro_tiles_per_row;
256
 
        GLint macro_tiles_per_slice;
257
 
        GLint slice_offset;
258
 
        GLint macro_tile_row_index;
259
 
        GLint macro_tile_column_index;
260
 
        GLint macro_tile_offset;
261
 
        GLint pixel_number = 0;
262
 
        GLint element_offset;
263
 
        GLint bank = 0;
264
 
        GLint channel = 0;
265
 
        GLint total_offset;
266
 
        GLint group_mask = (1 << group_bits) - 1;
267
 
        GLint offset_low;
268
 
        GLint offset_high;
269
 
        GLint offset = 0;
270
 
 
271
 
        switch (num_channels) {
272
 
        case 2:
273
 
        default:
274
 
                // channel[0] = x[3] ^ y[3]
275
 
                channel |= (((x >> 3) ^ (y >> 3)) & 1) << 0;
276
 
                break;
277
 
        case 4:
278
 
                // channel[0] = x[4] ^ y[3]
279
 
                channel |= (((x >> 4) ^ (y >> 3)) & 1) << 0;
280
 
                // channel[1] = x[3] ^ y[4]
281
 
                channel |= (((x >> 3) ^ (y >> 4)) & 1) << 1;
282
 
                break;
283
 
        case 8:
284
 
                // channel[0] = x[5] ^ y[3]
285
 
                channel |= (((x >> 5) ^ (y >> 3)) & 1) << 0;
286
 
                // channel[0] = x[4] ^ x[5] ^ y[4]
287
 
                channel |= (((x >> 4) ^ (x >> 5) ^ (y >> 4)) & 1) << 1;
288
 
                // channel[0] = x[3] ^ y[5]
289
 
                channel |= (((x >> 3) ^ (y >> 5)) & 1) << 2;
290
 
                break;
291
 
        }
292
 
 
293
 
        switch (num_banks) {
294
 
        case 4:
295
 
                // bank[0] = x[3] ^ y[4 + log2(num_channels)]
296
 
                bank |= (((x >> 3) ^ (y >> (4 + channel_bits))) & 1) << 0;
297
 
                if (r7xx_bank_op)
298
 
                        // bank[1] = x[3] ^ y[4 + log2(num_channels)] ^ x[5]
299
 
                        bank |= (((x >> 4) ^ (y >> (3 + channel_bits)) ^ (x >> 5)) & 1) << 1;
300
 
                else
301
 
                        // bank[1] = x[4] ^ y[3 + log2(num_channels)]
302
 
                        bank |= (((x >> 4) ^ (y >> (3 + channel_bits))) & 1) << 1;
303
 
                break;
304
 
        case 8:
305
 
                // bank[0] = x[3] ^ y[5 + log2(num_channels)]
306
 
                bank |= (((x >> 3) ^ (y >> (5 + channel_bits))) & 1) << 0;
307
 
                // bank[1] = x[4] ^ y[4 + log2(num_channels)] ^ y[5 + log2(num_channels)]
308
 
                bank |= (((x >> 4) ^ (y >> (4 + channel_bits)) ^ (y >> (5 + channel_bits))) & 1) << 1;
309
 
                if (r7xx_bank_op)
310
 
                        // bank[2] = x[5] ^ y[3 + log2(num_channels)] ^ x[6]
311
 
                        bank |= (((x >> 5) ^ (y >> (3 + channel_bits)) ^ (x >> 6)) & 1) << 2;
312
 
                else
313
 
                        // bank[2] = x[5] ^ y[3 + log2(num_channels)]
314
 
                        bank |= (((x >> 5) ^ (y >> (3 + channel_bits))) & 1) << 2;
315
 
                break;
316
 
        }
317
 
 
318
 
        tile_bytes = tile_width * tile_height * tile_thickness * element_bytes * num_samples;
319
 
        macro_tile_bytes = macro_tile_width * macro_tile_height * tile_bytes;
320
 
        macro_tiles_per_row = pitch_elements / macro_tile_width;
321
 
        macro_tiles_per_slice = macro_tiles_per_row * (height / macro_tile_height);
322
 
        slice_offset = (z / tile_thickness) * macro_tiles_per_slice * macro_tile_bytes;
323
 
        macro_tile_row_index = (y / tile_height) / macro_tile_height;
324
 
        macro_tile_column_index = (x / tile_width) / macro_tile_width;
325
 
        macro_tile_offset = ((macro_tile_row_index * macro_tiles_per_row) + macro_tile_column_index) * macro_tile_bytes;
326
 
 
327
 
        if (is_depth) {
328
 
                GLint pixel_offset = 0;
329
 
 
330
 
                pixel_number |= ((x >> 0) & 1) << 0; // pn[0] = x[0]
331
 
                pixel_number |= ((y >> 0) & 1) << 1; // pn[1] = y[0]
332
 
                pixel_number |= ((x >> 1) & 1) << 2; // pn[2] = x[1]
333
 
                pixel_number |= ((y >> 1) & 1) << 3; // pn[3] = y[1]
334
 
                pixel_number |= ((x >> 2) & 1) << 4; // pn[4] = x[2]
335
 
                pixel_number |= ((y >> 2) & 1) << 5; // pn[5] = y[2]
336
 
                switch (element_bytes) {
337
 
                case 2:
338
 
                        pixel_offset = pixel_number * element_bytes * num_samples;
339
 
                        break;
340
 
                case 4:
341
 
                        /* stencil and depth data are stored separately within a tile.
342
 
                         * stencil is stored in a contiguous tile before the depth tile.
343
 
                         * stencil element is 1 byte, depth element is 3 bytes.
344
 
                         * stencil tile is 64 bytes.
345
 
                         */
346
 
                        if (is_stencil)
347
 
                                pixel_offset = pixel_number * 1 * num_samples;
348
 
                        else
349
 
                                pixel_offset = (pixel_number * 3 * num_samples) + 64;
350
 
                        break;
351
 
                }
352
 
                element_offset = pixel_offset + (sample_number * element_bytes);
353
 
        } else {
354
 
                GLint sample_offset;
355
 
 
356
 
                switch (element_bytes) {
357
 
                case 1:
358
 
                        pixel_number |= ((x >> 0) & 1) << 0; // pn[0] = x[0]
359
 
                        pixel_number |= ((x >> 1) & 1) << 1; // pn[1] = x[1]
360
 
                        pixel_number |= ((x >> 2) & 1) << 2; // pn[2] = x[2]
361
 
                        pixel_number |= ((y >> 1) & 1) << 3; // pn[3] = y[1]
362
 
                        pixel_number |= ((y >> 0) & 1) << 4; // pn[4] = y[0]
363
 
                        pixel_number |= ((y >> 2) & 1) << 5; // pn[5] = y[2]
364
 
                        break;
365
 
                case 2:
366
 
                        pixel_number |= ((x >> 0) & 1) << 0; // pn[0] = x[0]
367
 
                        pixel_number |= ((x >> 1) & 1) << 1; // pn[1] = x[1]
368
 
                        pixel_number |= ((x >> 2) & 1) << 2; // pn[2] = x[2]
369
 
                        pixel_number |= ((y >> 0) & 1) << 3; // pn[3] = y[0]
370
 
                        pixel_number |= ((y >> 1) & 1) << 4; // pn[4] = y[1]
371
 
                        pixel_number |= ((y >> 2) & 1) << 5; // pn[5] = y[2]
372
 
                        break;
373
 
                case 4:
374
 
                        pixel_number |= ((x >> 0) & 1) << 0; // pn[0] = x[0]
375
 
                        pixel_number |= ((x >> 1) & 1) << 1; // pn[1] = x[1]
376
 
                        pixel_number |= ((y >> 0) & 1) << 2; // pn[2] = y[0]
377
 
                        pixel_number |= ((x >> 2) & 1) << 3; // pn[3] = x[2]
378
 
                        pixel_number |= ((y >> 1) & 1) << 4; // pn[4] = y[1]
379
 
                        pixel_number |= ((y >> 2) & 1) << 5; // pn[5] = y[2]
380
 
                        break;
381
 
                }
382
 
                sample_offset = sample_number * (tile_bytes / num_samples);
383
 
                element_offset = sample_offset + (pixel_number * element_bytes);
384
 
        }
385
 
        total_offset = (slice_offset + macro_tile_offset) >> (channel_bits + bank_bits);
386
 
        total_offset += element_offset;
387
 
 
388
 
        offset_low = total_offset & group_mask;
389
 
        offset_high = (total_offset & ~group_mask) << (channel_bits + bank_bits);
390
 
        offset = (bank << (group_bits + channel_bits)) + (channel << group_bits) + offset_low + offset_high;
391
 
 
392
 
        return offset;
393
 
}
394
 
 
395
 
/* depth buffers */
396
 
static GLubyte *r600_ptr_depth(const struct radeon_renderbuffer * rrb,
397
 
                               GLint x, GLint y)
398
 
{
399
 
    GLubyte *ptr = rrb->bo->ptr;
400
 
    GLint offset;
401
 
    if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE)
402
 
            offset = r600_2d_tile_helper(rrb, x, y, 1, 0);
403
 
    else
404
 
            offset = r600_1d_tile_helper(rrb, x, y, 1, 0);
405
 
    return &ptr[offset];
406
 
}
407
 
 
408
 
static GLubyte *r600_ptr_stencil(const struct radeon_renderbuffer * rrb,
409
 
                                 GLint x, GLint y)
410
 
{
411
 
    GLubyte *ptr = rrb->bo->ptr;
412
 
    GLint offset;
413
 
    if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE)
414
 
            offset = r600_2d_tile_helper(rrb, x, y, 1, 1);
415
 
    else
416
 
            offset = r600_1d_tile_helper(rrb, x, y, 1, 1);
417
 
    return &ptr[offset];
418
 
}
419
 
 
420
 
static GLubyte *r600_ptr_color(const struct radeon_renderbuffer * rrb,
421
 
                               GLint x, GLint y)
422
 
{
423
 
    GLubyte *ptr = rrb->bo->ptr;
424
 
    uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE;
425
 
    GLint offset;
426
 
 
427
 
    if (rrb->has_surface || !(rrb->bo->flags & mask)) {
428
 
        offset = x * rrb->cpp + y * rrb->pitch;
429
 
    } else {
430
 
            if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE)
431
 
                    offset = r600_2d_tile_helper(rrb, x, y, 0, 0);
432
 
            else
433
 
                    offset = r600_1d_tile_helper(rrb, x, y, 0, 0);
434
 
    }
435
 
    return &ptr[offset];
436
 
}
437
 
 
438
 
#else
439
 
 
440
 
/* radeon tiling on r300-r500 has 4 states,
441
 
   macro-linear/micro-linear
442
 
   macro-linear/micro-tiled
443
 
   macro-tiled /micro-linear
444
 
   macro-tiled /micro-tiled
445
 
   1 byte surface 
446
 
   2 byte surface - two types - we only provide 8x2 microtiling
447
 
   4 byte surface
448
 
   8/16 byte (unused)
449
 
*/
450
 
static GLubyte *radeon_ptr_4byte(const struct radeon_renderbuffer * rrb,
451
 
                             GLint x, GLint y)
452
 
{
453
 
    GLubyte *ptr = rrb->bo->ptr + rrb->draw_offset;
454
 
    uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE;
455
 
    GLint offset;
456
 
 
457
 
    if (rrb->has_surface || !(rrb->bo->flags & mask)) {
458
 
        offset = x * rrb->cpp + y * rrb->pitch;
459
 
    } else {
460
 
        offset = 0;
461
 
        if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) {
462
 
            if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) {
463
 
                offset = ((y >> 4) * (rrb->pitch >> 7) + (x >> 5)) << 11;
464
 
                offset += (((y >> 3) ^ (x >> 5)) & 0x1) << 10;
465
 
                offset += (((y >> 4) ^ (x >> 4)) & 0x1) << 9;
466
 
                offset += (((y >> 2) ^ (x >> 4)) & 0x1) << 8;
467
 
                offset += (((y >> 3) ^ (x >> 3)) & 0x1) << 7;
468
 
                offset += ((y >> 1) & 0x1) << 6;
469
 
                offset += ((x >> 2) & 0x1) << 5;
470
 
                offset += (y & 1) << 4;
471
 
                offset += (x & 3) << 2;
472
 
            } else {
473
 
                offset = ((y >> 3) * (rrb->pitch >> 8) + (x >> 6)) << 11;
474
 
                offset += (((y >> 2) ^ (x >> 6)) & 0x1) << 10;
475
 
                offset += (((y >> 3) ^ (x >> 5)) & 0x1) << 9;
476
 
                offset += (((y >> 1) ^ (x >> 5)) & 0x1) << 8;
477
 
                offset += (((y >> 2) ^ (x >> 4)) & 0x1) << 7;
478
 
                offset += (y & 1) << 6;
479
 
                offset += (x & 15) << 2;
480
 
            }
481
 
        } else {
482
 
            offset = ((y >> 1) * (rrb->pitch >> 4) + (x >> 2)) << 5;
483
 
            offset += (y & 1) << 4;
484
 
            offset += (x & 3) << 2;
485
 
        }
486
 
    }
487
 
    return &ptr[offset];
488
 
}
489
 
 
490
 
static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
491
 
                                     GLint x, GLint y)
492
 
{
493
 
    GLubyte *ptr = rrb->bo->ptr + rrb->draw_offset;
494
 
    uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE;
495
 
    GLint offset;
496
 
 
497
 
    if (rrb->has_surface || !(rrb->bo->flags & mask)) {
498
 
        offset = x * rrb->cpp + y * rrb->pitch;
499
 
    } else {
500
 
        offset = 0;
501
 
        if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) {
502
 
            if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) {
503
 
                offset = ((y >> 4) * (rrb->pitch >> 7) + (x >> 6)) << 11;
504
 
                offset += (((y >> 3) ^ (x >> 6)) & 0x1) << 10;
505
 
                offset += (((y >> 4) ^ (x >> 5)) & 0x1) << 9;
506
 
                offset += (((y >> 2) ^ (x >> 5)) & 0x1) << 8;
507
 
                offset += (((y >> 3) ^ (x >> 4)) & 0x1) << 7;
508
 
                offset += ((y >> 1) & 0x1) << 6;
509
 
                offset += ((x >> 3) & 0x1) << 5;
510
 
                offset += (y & 1) << 4;
511
 
                offset += (x & 3) << 2;
512
 
            } else {
513
 
                offset = ((y >> 3) * (rrb->pitch >> 8) + (x >> 7)) << 11;
514
 
                offset += (((y >> 2) ^ (x >> 7)) & 0x1) << 10;
515
 
                offset += (((y >> 3) ^ (x >> 6)) & 0x1) << 9;
516
 
                offset += (((y >> 1) ^ (x >> 6)) & 0x1) << 8;
517
 
                offset += (((y >> 2) ^ (x >> 5)) & 0x1) << 7;
518
 
                offset += (y & 1) << 6;
519
 
                offset += ((x >> 4) & 0x1) << 5;
520
 
                offset += (x & 15) << 2;
521
 
            }
522
 
        } else {
523
 
            offset = ((y >> 1) * (rrb->pitch >> 4) + (x >> 3)) << 5;
524
 
            offset += (y & 0x1) << 4;
525
 
            offset += (x & 0x7) << 1;
526
 
        }
527
 
    }
528
 
    return &ptr[offset];
529
 
}
530
 
 
531
 
#endif
532
 
 
533
 
/*
534
 
 * Note that all information needed to access pixels in a renderbuffer
535
 
 * should be obtained through the gl_renderbuffer parameter, not per-context
536
 
 * information.
537
 
 */
538
 
#define LOCAL_VARS                                              \
539
 
   struct radeon_context *radeon = RADEON_CONTEXT(ctx);                 \
540
 
   struct radeon_renderbuffer *rrb = (void *) rb;               \
541
 
   const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1;                 \
542
 
   const GLint yBias = ctx->DrawBuffer->Name ? 0 : rrb->base.Height - 1;\
543
 
   unsigned int num_cliprects;                                          \
544
 
   struct drm_clip_rect *cliprects;                                     \
545
 
   int x_off, y_off;                                                    \
546
 
   GLuint p;                                            \
547
 
   (void)p;                                             \
548
 
   radeon_get_cliprects(radeon, &cliprects, &num_cliprects, &x_off, &y_off);
549
 
 
550
 
#define LOCAL_DEPTH_VARS                                \
551
 
   struct radeon_context *radeon = RADEON_CONTEXT(ctx);                 \
552
 
   struct radeon_renderbuffer *rrb = (void *) rb;       \
553
 
   const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1;                 \
554
 
   const GLint yBias = ctx->DrawBuffer->Name ? 0 : rrb->base.Height - 1;\
555
 
   unsigned int num_cliprects;                                          \
556
 
   struct drm_clip_rect *cliprects;                                     \
557
 
   int x_off, y_off;                                                    \
558
 
  radeon_get_cliprects(radeon, &cliprects, &num_cliprects, &x_off, &y_off);
559
 
 
560
 
#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
561
 
 
562
 
#define Y_FLIP(_y) ((_y) * yScale + yBias)
563
 
 
564
 
#define HW_LOCK()
565
 
 
566
 
#define HW_UNLOCK()
567
 
 
568
 
/* XXX FBO: this is identical to the macro in spantmp2.h except we get
569
 
 * the cliprect info from the context, not the driDrawable.
570
 
 * Move this into spantmp2.h someday.
571
 
 */
572
 
#define HW_CLIPLOOP()                                                   \
573
 
   do {                                                                 \
574
 
      int _nc = num_cliprects;                                          \
575
 
      while ( _nc-- ) {                                                 \
576
 
         int minx = cliprects[_nc].x1 - x_off;                          \
577
 
         int miny = cliprects[_nc].y1 - y_off;                          \
578
 
         int maxx = cliprects[_nc].x2 - x_off;                          \
579
 
         int maxy = cliprects[_nc].y2 - y_off;
580
 
 
581
 
/* ================================================================
582
 
 * Color buffer
583
 
 */
584
 
 
585
 
/* 16 bit, RGB565 color spanline and pixel functions
586
 
 */
587
 
#define SPANTMP_PIXEL_FMT GL_RGB
588
 
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
589
 
 
590
 
#define TAG(x)    radeon##x##_RGB565
591
 
#define TAG2(x,y) radeon##x##_RGB565##y
592
 
#if defined(RADEON_R600)
593
 
#define GET_VALUE(_x, _y) (LE16_TO_CPU(*(GLushort*)(r600_ptr_color(rrb, _x + x_off, _y + y_off))))
594
 
#define PUT_VALUE(_x, _y, d) { \
595
 
   GLushort *_ptr = (GLushort*)r600_ptr_color( rrb, _x + x_off, _y + y_off );           \
596
 
   *_ptr = CPU_TO_LE16(d);                                                              \
597
 
} while (0)
598
 
#else
599
 
#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off)
600
 
#endif
601
 
#include "spantmp2.h"
602
 
 
603
 
#define SPANTMP_PIXEL_FMT GL_RGB
604
 
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5_REV
605
 
 
606
 
#define TAG(x)    radeon##x##_RGB565_REV
607
 
#define TAG2(x,y) radeon##x##_RGB565_REV##y
608
 
#if defined(RADEON_R600)
609
 
#define GET_VALUE(_x, _y) (LE16_TO_CPU(*(GLushort*)(r600_ptr_color(rrb, _x + x_off, _y + y_off))))
610
 
#define PUT_VALUE(_x, _y, d) { \
611
 
   GLushort *_ptr = (GLushort*)r600_ptr_color( rrb, _x + x_off, _y + y_off );           \
612
 
   *_ptr = CPU_TO_LE16(d);                                                              \
613
 
} while (0)
614
 
#else
615
 
#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off)
616
 
#endif
617
 
#include "spantmp2.h"
618
 
 
619
 
/* 16 bit, ARGB1555 color spanline and pixel functions
620
 
 */
621
 
#define SPANTMP_PIXEL_FMT GL_BGRA
622
 
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5_REV
623
 
 
624
 
#define TAG(x)    radeon##x##_ARGB1555
625
 
#define TAG2(x,y) radeon##x##_ARGB1555##y
626
 
#if defined(RADEON_R600)
627
 
#define GET_VALUE(_x, _y) (LE16_TO_CPU(*(GLushort*)(r600_ptr_color(rrb, _x + x_off, _y + y_off))))
628
 
#define PUT_VALUE(_x, _y, d) { \
629
 
   GLushort *_ptr = (GLushort*)r600_ptr_color( rrb, _x + x_off, _y + y_off );           \
630
 
   *_ptr = CPU_TO_LE16(d);                                                              \
631
 
} while (0)
632
 
#else
633
 
#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off)
634
 
#endif
635
 
#include "spantmp2.h"
636
 
 
637
 
#define SPANTMP_PIXEL_FMT GL_BGRA
638
 
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5
639
 
 
640
 
#define TAG(x)    radeon##x##_ARGB1555_REV
641
 
#define TAG2(x,y) radeon##x##_ARGB1555_REV##y
642
 
#if defined(RADEON_R600)
643
 
#define GET_VALUE(_x, _y) (LE16_TO_CPU(*(GLushort*)(r600_ptr_color(rrb, _x + x_off, _y + y_off))))
644
 
#define PUT_VALUE(_x, _y, d) { \
645
 
   GLushort *_ptr = (GLushort*)r600_ptr_color( rrb, _x + x_off, _y + y_off );           \
646
 
   *_ptr = CPU_TO_LE16(d);                                                              \
647
 
} while (0)
648
 
#else
649
 
#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off)
650
 
#endif
651
 
#include "spantmp2.h"
652
 
 
653
 
/* 16 bit, RGBA4 color spanline and pixel functions
654
 
 */
655
 
#define SPANTMP_PIXEL_FMT GL_BGRA
656
 
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4_REV
657
 
 
658
 
#define TAG(x)    radeon##x##_ARGB4444
659
 
#define TAG2(x,y) radeon##x##_ARGB4444##y
660
 
#if defined(RADEON_R600)
661
 
#define GET_VALUE(_x, _y) (LE16_TO_CPU(*(GLushort*)(r600_ptr_color(rrb, _x + x_off, _y + y_off))))
662
 
#define PUT_VALUE(_x, _y, d) { \
663
 
   GLushort *_ptr = (GLushort*)r600_ptr_color( rrb, _x + x_off, _y + y_off );           \
664
 
   *_ptr = CPU_TO_LE16(d);                                                              \
665
 
} while (0)
666
 
#else
667
 
#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off)
668
 
#endif
669
 
#include "spantmp2.h"
670
 
 
671
 
#define SPANTMP_PIXEL_FMT GL_BGRA
672
 
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4
673
 
 
674
 
#define TAG(x)    radeon##x##_ARGB4444_REV
675
 
#define TAG2(x,y) radeon##x##_ARGB4444_REV##y
676
 
#if defined(RADEON_R600)
677
 
#define GET_VALUE(_x, _y) (LE16_TO_CPU(*(GLushort*)(r600_ptr_color(rrb, _x + x_off, _y + y_off))))
678
 
#define PUT_VALUE(_x, _y, d) { \
679
 
   GLushort *_ptr = (GLushort*)r600_ptr_color( rrb, _x + x_off, _y + y_off );           \
680
 
   *_ptr = CPU_TO_LE16(d);                                                              \
681
 
} while (0)
682
 
#else
683
 
#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off)
684
 
#endif
685
 
#include "spantmp2.h"
686
 
 
687
 
/* 32 bit, xRGB8888 color spanline and pixel functions
688
 
 */
689
 
#define SPANTMP_PIXEL_FMT GL_BGRA
690
 
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
691
 
 
692
 
#define TAG(x)    radeon##x##_xRGB8888
693
 
#define TAG2(x,y) radeon##x##_xRGB8888##y
694
 
#if defined(RADEON_R600)
695
 
#define GET_VALUE(_x, _y) ((LE32_TO_CPU(*(GLuint*)(r600_ptr_color(rrb, _x + x_off, _y + y_off))) | 0xff000000))
696
 
#define PUT_VALUE(_x, _y, d) { \
697
 
   GLuint *_ptr = (GLuint*)r600_ptr_color( rrb, _x + x_off, _y + y_off );               \
698
 
   *_ptr = CPU_TO_LE32(d);                                                              \
699
 
} while (0)
700
 
#else
701
 
#define GET_VALUE(_x, _y) ((*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)) | 0xff000000))
702
 
#define PUT_VALUE(_x, _y, d) { \
703
 
   GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off );             \
704
 
   *_ptr = d;                                                           \
705
 
} while (0)
706
 
#endif
707
 
#include "spantmp2.h"
708
 
 
709
 
/* 32 bit, ARGB8888 color spanline and pixel functions
710
 
 */
711
 
#define SPANTMP_PIXEL_FMT GL_BGRA
712
 
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
713
 
 
714
 
#define TAG(x)    radeon##x##_ARGB8888
715
 
#define TAG2(x,y) radeon##x##_ARGB8888##y
716
 
#if defined(RADEON_R600)
717
 
#define GET_VALUE(_x, _y) (LE32_TO_CPU(*(GLuint*)(r600_ptr_color(rrb, _x + x_off, _y + y_off))))
718
 
#define PUT_VALUE(_x, _y, d) { \
719
 
   GLuint *_ptr = (GLuint*)r600_ptr_color( rrb, _x + x_off, _y + y_off );               \
720
 
   *_ptr = CPU_TO_LE32(d);                                                              \
721
 
} while (0)
722
 
#else
723
 
#define GET_VALUE(_x, _y) (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)))
724
 
#define PUT_VALUE(_x, _y, d) { \
725
 
   GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off );             \
726
 
   *_ptr = d;                                                           \
727
 
} while (0)
728
 
#endif
729
 
#include "spantmp2.h"
730
 
 
731
 
/* 32 bit, BGRx8888 color spanline and pixel functions
732
 
 */
733
 
#define SPANTMP_PIXEL_FMT GL_BGRA
734
 
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8
735
 
 
736
 
#define TAG(x)    radeon##x##_BGRx8888
737
 
#define TAG2(x,y) radeon##x##_BGRx8888##y
738
 
#if defined(RADEON_R600)
739
 
#define GET_VALUE(_x, _y) ((LE32_TO_CPU(*(GLuint*)(r600_ptr_color(rrb, _x + x_off, _y + y_off))) | 0x000000ff))
740
 
#define PUT_VALUE(_x, _y, d) { \
741
 
   GLuint *_ptr = (GLuint*)r600_ptr_color( rrb, _x + x_off, _y + y_off );               \
742
 
   *_ptr = CPU_TO_LE32(d);                                                              \
743
 
} while (0)
744
 
#else
745
 
#define GET_VALUE(_x, _y) ((*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)) | 0x000000ff))
746
 
#define PUT_VALUE(_x, _y, d) { \
747
 
   GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off );             \
748
 
   *_ptr = d;                                                           \
749
 
} while (0)
750
 
#endif
751
 
#include "spantmp2.h"
752
 
 
753
 
/* 32 bit, BGRA8888 color spanline and pixel functions
754
 
 */
755
 
#define SPANTMP_PIXEL_FMT GL_BGRA
756
 
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8
757
 
 
758
 
#define TAG(x)    radeon##x##_BGRA8888
759
 
#define TAG2(x,y) radeon##x##_BGRA8888##y
760
 
#if defined(RADEON_R600)
761
 
#define GET_VALUE(_x, _y) (LE32_TO_CPU(*(GLuint*)(r600_ptr_color(rrb, _x + x_off, _y + y_off))))
762
 
#define PUT_VALUE(_x, _y, d) { \
763
 
   GLuint *_ptr = (GLuint*)r600_ptr_color( rrb, _x + x_off, _y + y_off );               \
764
 
   *_ptr = CPU_TO_LE32(d);                                                              \
765
 
} while (0)
766
 
#else
767
 
#define GET_PTR(X,Y) radeon_ptr_4byte(rrb, (X) + x_off, (Y) + y_off)
768
 
#endif
769
 
#include "spantmp2.h"
770
 
 
771
 
/* ================================================================
772
 
 * Depth buffer
773
 
 */
774
 
 
775
 
/* The Radeon family has depth tiling on all the time, so we have to convert
776
 
 * the x,y coordinates into the memory bus address (mba) in the same
777
 
 * manner as the engine.  In each case, the linear block address (ba)
778
 
 * is calculated, and then wired with x and y to produce the final
779
 
 * memory address.
780
 
 * The chip will do address translation on its own if the surface registers
781
 
 * are set up correctly. It is not quite enough to get it working with hyperz
782
 
 * too...
783
 
 */
784
 
 
785
 
/* 16-bit depth buffer functions
786
 
 */
787
 
#define VALUE_TYPE GLushort
788
 
 
789
 
#if defined(RADEON_R200)
790
 
#define WRITE_DEPTH( _x, _y, d )                                        \
791
 
   *(GLushort *)r200_depth_2byte(rrb, _x + x_off, _y + y_off) = d
792
 
#elif defined(RADEON_R600)
793
 
#define WRITE_DEPTH( _x, _y, d )                                        \
794
 
   *(GLushort *)r600_ptr_depth(rrb, _x + x_off, _y + y_off) = CPU_TO_LE16(d)
795
 
#else
796
 
#define WRITE_DEPTH( _x, _y, d )                                        \
797
 
   *(GLushort *)radeon_ptr_2byte_8x2(rrb, _x + x_off, _y + y_off) = d
798
 
#endif
799
 
 
800
 
#if defined(RADEON_R200)
801
 
#define READ_DEPTH( d, _x, _y )                                         \
802
 
   d = *(GLushort *)r200_depth_2byte(rrb, _x + x_off, _y + y_off)
803
 
#elif defined(RADEON_R600)
804
 
#define READ_DEPTH( d, _x, _y )                                         \
805
 
   d = LE16_TO_CPU(*(GLushort *)r600_ptr_depth(rrb, _x + x_off, _y + y_off))
806
 
#else
807
 
#define READ_DEPTH( d, _x, _y )                                         \
808
 
   d = *(GLushort *)radeon_ptr_2byte_8x2(rrb, _x + x_off, _y + y_off)
809
 
#endif
810
 
 
811
 
#define TAG(x) radeon##x##_z16
812
 
#include "depthtmp.h"
813
 
 
814
 
/* 24 bit depth
815
 
 *
816
 
 * Careful: It looks like the R300 uses ZZZS byte order while the R200
817
 
 * uses SZZZ for 24 bit depth, 8 bit stencil mode.
818
 
 */
819
 
#define VALUE_TYPE GLuint
820
 
 
821
 
#if defined(RADEON_R300)
822
 
#define WRITE_DEPTH( _x, _y, d )                                        \
823
 
do {                                                                    \
824
 
   GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off );             \
825
 
   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
826
 
   tmp &= 0x000000ff;                                                   \
827
 
   tmp |= ((d << 8) & 0xffffff00);                                      \
828
 
   *_ptr = CPU_TO_LE32(tmp);                                            \
829
 
} while (0)
830
 
#elif defined(RADEON_R600)
831
 
#define WRITE_DEPTH( _x, _y, d )                                        \
832
 
do {                                                                    \
833
 
   GLuint *_ptr = (GLuint*)r600_ptr_depth( rrb, _x + x_off, _y + y_off );               \
834
 
   GLuint tmp = LE32_TO_CPU(*_ptr);                             \
835
 
   tmp &= 0xff000000;                                                   \
836
 
   tmp |= ((d) & 0x00ffffff);                                   \
837
 
   *_ptr = CPU_TO_LE32(tmp);                                    \
838
 
} while (0)
839
 
#elif defined(RADEON_R200)
840
 
#define WRITE_DEPTH( _x, _y, d )                                        \
841
 
do {                                                                    \
842
 
   GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x + x_off, _y + y_off );             \
843
 
   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
844
 
   tmp &= 0xff000000;                                                   \
845
 
   tmp |= ((d) & 0x00ffffff);                                           \
846
 
   *_ptr = CPU_TO_LE32(tmp);                                            \
847
 
} while (0)
848
 
#else
849
 
#define WRITE_DEPTH( _x, _y, d )                                        \
850
 
do {                                                                    \
851
 
   GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off );     \
852
 
   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
853
 
   tmp &= 0xff000000;                                                   \
854
 
   tmp |= ((d) & 0x00ffffff);                                           \
855
 
   *_ptr = CPU_TO_LE32(tmp);                                            \
856
 
} while (0)
857
 
#endif
858
 
 
859
 
#if defined(RADEON_R300)
860
 
#define READ_DEPTH( d, _x, _y )                                         \
861
 
  do {                                                                  \
862
 
    d = (LE32_TO_CPU(*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off))) & 0xffffff00) >> 8; \
863
 
  }while(0)
864
 
#elif defined(RADEON_R600)
865
 
#define READ_DEPTH( d, _x, _y )                                         \
866
 
  do {                                                                  \
867
 
    d = (LE32_TO_CPU(*(GLuint*)(r600_ptr_depth(rrb, _x + x_off, _y + y_off))) & 0x00ffffff); \
868
 
  }while(0)
869
 
#elif defined(RADEON_R200)
870
 
#define READ_DEPTH( d, _x, _y )                                         \
871
 
  do {                                                                  \
872
 
    d = LE32_TO_CPU(*(GLuint*)(r200_depth_4byte(rrb, _x + x_off, _y + y_off))) & 0x00ffffff; \
873
 
  }while(0)
874
 
#else
875
 
#define READ_DEPTH( d, _x, _y ) \
876
 
  d = LE32_TO_CPU(*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off,  _y + y_off))) & 0x00ffffff;
877
 
#endif
878
 
 
879
 
#define TAG(x) radeon##x##_z24
880
 
#include "depthtmp.h"
881
 
 
882
 
/* 24 bit depth, 8 bit stencil depthbuffer functions
883
 
 * EXT_depth_stencil
884
 
 *
885
 
 * Careful: It looks like the R300 uses ZZZS byte order while the R200
886
 
 * uses SZZZ for 24 bit depth, 8 bit stencil mode.
887
 
 */
888
 
#define VALUE_TYPE GLuint
889
 
 
890
 
#if defined(RADEON_R300)
891
 
#define WRITE_DEPTH( _x, _y, d )                                        \
892
 
do {                                                                    \
893
 
   GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off );             \
894
 
   *_ptr = CPU_TO_LE32((((d) & 0xff000000) >> 24) | (((d) & 0x00ffffff) << 8));   \
895
 
} while (0)
896
 
#elif defined(RADEON_R600)
897
 
#define WRITE_DEPTH( _x, _y, d )                                        \
898
 
do {                                                                    \
899
 
   GLuint *_ptr = (GLuint*)r600_ptr_depth( rrb, _x + x_off, _y + y_off );               \
900
 
   GLuint tmp = LE32_TO_CPU(*_ptr);                             \
901
 
   tmp &= 0xff000000;                                                   \
902
 
   tmp |= ((d) & 0x00ffffff);                                   \
903
 
   *_ptr = CPU_TO_LE32(tmp);                                    \
904
 
   _ptr = (GLuint*)r600_ptr_stencil(rrb, _x + x_off, _y + y_off);               \
905
 
   tmp = LE32_TO_CPU(*_ptr);                            \
906
 
   tmp &= 0xffffff00;                                                   \
907
 
   tmp |= ((d) >> 24) & 0xff;                                           \
908
 
   *_ptr = CPU_TO_LE32(tmp);                                    \
909
 
} while (0)
910
 
#elif defined(RADEON_R200)
911
 
#define WRITE_DEPTH( _x, _y, d )                                        \
912
 
do {                                                                    \
913
 
   GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x + x_off, _y + y_off );             \
914
 
   *_ptr = CPU_TO_LE32(d);                                              \
915
 
} while (0)
916
 
#else
917
 
#define WRITE_DEPTH( _x, _y, d )                                        \
918
 
do {                                                                    \
919
 
   GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off );     \
920
 
   *_ptr = CPU_TO_LE32(d);                                              \
921
 
} while (0)
922
 
#endif
923
 
 
924
 
#if defined(RADEON_R300)
925
 
#define READ_DEPTH( d, _x, _y )                                         \
926
 
  do { \
927
 
    GLuint tmp = (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)));   \
928
 
    d = LE32_TO_CPU(((tmp & 0x000000ff) << 24) | ((tmp & 0xffffff00) >> 8));    \
929
 
  }while(0)
930
 
#elif defined(RADEON_R600)
931
 
#define READ_DEPTH( d, _x, _y )                                         \
932
 
  do { \
933
 
    d = (LE32_TO_CPU(*(GLuint*)(r600_ptr_depth(rrb, _x + x_off, _y + y_off))) & 0x00ffffff); \
934
 
    d |= ((LE32_TO_CPU(*(GLuint*)(r600_ptr_stencil(rrb, _x + x_off, _y + y_off))) << 24) & 0xff000000); \
935
 
  }while(0)
936
 
#elif defined(RADEON_R200)
937
 
#define READ_DEPTH( d, _x, _y )                                         \
938
 
  do { \
939
 
    d = LE32_TO_CPU(*(GLuint*)(r200_depth_4byte(rrb, _x + x_off, _y + y_off))); \
940
 
  }while(0)
941
 
#else
942
 
#define READ_DEPTH( d, _x, _y ) do {                                    \
943
 
    d = LE32_TO_CPU(*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off))); \
944
 
  } while (0)
945
 
#endif
946
 
 
947
 
#define TAG(x) radeon##x##_s8_z24
948
 
#include "depthtmp.h"
949
 
 
950
 
/* ================================================================
951
 
 * Stencil buffer
952
 
 */
953
 
 
954
 
/* 24 bit depth, 8 bit stencil depthbuffer functions
955
 
 */
956
 
#ifdef RADEON_R300
957
 
#define WRITE_STENCIL( _x, _y, d )                                      \
958
 
do {                                                                    \
959
 
   GLuint *_ptr = (GLuint*)radeon_ptr_4byte(rrb, _x + x_off, _y + y_off);               \
960
 
   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
961
 
   tmp &= 0xffffff00;                                                   \
962
 
   tmp |= (d) & 0xff;                                                   \
963
 
   *_ptr = CPU_TO_LE32(tmp);                                            \
964
 
} while (0)
965
 
#elif defined(RADEON_R600)
966
 
#define WRITE_STENCIL( _x, _y, d )                                      \
967
 
do {                                                                    \
968
 
   GLuint *_ptr = (GLuint*)r600_ptr_stencil(rrb, _x + x_off, _y + y_off);               \
969
 
   GLuint tmp = LE32_TO_CPU(*_ptr);                             \
970
 
   tmp &= 0xffffff00;                                                   \
971
 
   tmp |= (d) & 0xff;                                                   \
972
 
   *_ptr = CPU_TO_LE32(tmp);                                    \
973
 
} while (0)
974
 
#elif defined(RADEON_R200)
975
 
#define WRITE_STENCIL( _x, _y, d )                                      \
976
 
do {                                                                    \
977
 
   GLuint *_ptr = (GLuint*)r200_depth_4byte(rrb, _x + x_off, _y + y_off);               \
978
 
   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
979
 
   tmp &= 0x00ffffff;                                                   \
980
 
   tmp |= (((d) & 0xff) << 24);                                         \
981
 
   *_ptr = CPU_TO_LE32(tmp);                                            \
982
 
} while (0)
983
 
#else
984
 
#define WRITE_STENCIL( _x, _y, d )                                      \
985
 
do {                                                                    \
986
 
   GLuint *_ptr = (GLuint*)radeon_ptr_4byte(rrb, _x + x_off, _y + y_off);               \
987
 
   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
988
 
   tmp &= 0x00ffffff;                                                   \
989
 
   tmp |= (((d) & 0xff) << 24);                                         \
990
 
   *_ptr = CPU_TO_LE32(tmp);                                            \
991
 
} while (0)
992
 
#endif
993
 
 
994
 
#ifdef RADEON_R300
995
 
#define READ_STENCIL( d, _x, _y )                                       \
996
 
do {                                                                    \
997
 
   GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off );             \
998
 
   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
999
 
   d = tmp & 0x000000ff;                                                \
1000
 
} while (0)
1001
 
#elif defined(RADEON_R600)
1002
 
#define READ_STENCIL( d, _x, _y )                                       \
1003
 
do {                                                                    \
1004
 
   GLuint *_ptr = (GLuint*)r600_ptr_stencil( rrb, _x + x_off, _y + y_off );             \
1005
 
   GLuint tmp = LE32_TO_CPU(*_ptr);                             \
1006
 
   d = tmp & 0x000000ff;                                                \
1007
 
} while (0)
1008
 
#elif defined(RADEON_R200)
1009
 
#define READ_STENCIL( d, _x, _y )                                       \
1010
 
do {                                                                    \
1011
 
   GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x + x_off, _y + y_off );             \
1012
 
   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
1013
 
   d = (tmp & 0xff000000) >> 24;                                        \
1014
 
} while (0)
1015
 
#else
1016
 
#define READ_STENCIL( d, _x, _y )                                       \
1017
 
do {                                                                    \
1018
 
   GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off );             \
1019
 
   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
1020
 
   d = (tmp & 0xff000000) >> 24;                                        \
1021
 
} while (0)
1022
 
#endif
1023
 
 
1024
 
#define TAG(x) radeon##x##_s8_z24
1025
 
#include "stenciltmp.h"
1026
 
 
1027
 
 
1028
 
static void map_unmap_rb(struct gl_renderbuffer *rb, int flag)
1029
 
{
1030
 
        struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
1031
 
        int r;
1032
 
 
1033
 
        if (rrb == NULL || !rrb->bo)
1034
 
                return;
1035
 
 
1036
 
        radeon_print(RADEON_MEMORY, RADEON_TRACE,
1037
 
                "%s( rb %p, flag %s )\n",
1038
 
                __func__, rb, flag ? "true":"false");
1039
 
 
1040
 
        if (flag) {
1041
 
                radeon_bo_wait(rrb->bo);
1042
 
                r = radeon_bo_map(rrb->bo, 1);
1043
 
                if (r) {
1044
 
                        fprintf(stderr, "(%s) error(%d) mapping buffer.\n",
1045
 
                                __FUNCTION__, r);
1046
 
                }
1047
 
 
1048
 
                radeonSetSpanFunctions(rrb);
1049
 
        } else {
1050
 
                radeon_bo_unmap(rrb->bo);
1051
 
                rb->GetRow = NULL;
1052
 
                rb->PutRow = NULL;
1053
 
        }
1054
 
}
1055
 
 
1056
 
static void
1057
 
radeon_map_unmap_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
1058
 
                             GLboolean map)
1059
 
{
1060
 
        GLuint i, j;
1061
 
 
1062
 
        radeon_print(RADEON_MEMORY, RADEON_TRACE,
1063
 
                "%s( %p , fb %p, map %s )\n",
1064
 
                __func__, ctx, fb, map ? "true":"false");
1065
 
 
1066
 
        /* color draw buffers */
1067
 
        for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers; j++)
1068
 
                map_unmap_rb(fb->_ColorDrawBuffers[j], map);
1069
 
 
1070
 
        map_unmap_rb(fb->_ColorReadBuffer, map);
1071
 
 
1072
 
        /* check for render to textures */
1073
 
        for (i = 0; i < BUFFER_COUNT; i++) {
1074
 
                struct gl_renderbuffer_attachment *att =
1075
 
                        fb->Attachment + i;
1076
 
                struct gl_texture_object *tex = att->Texture;
1077
 
                if (tex) {
1078
 
                        /* Render to texture. Note that a mipmapped texture need not
1079
 
                         * be complete for render to texture, so we must restrict to
1080
 
                         * mapping only the attached image.
1081
 
                         */
1082
 
                        radeon_texture_image *image = get_radeon_texture_image(tex->Image[att->CubeMapFace][att->TextureLevel]);
1083
 
                        ASSERT(att->Renderbuffer);
1084
 
 
1085
 
                        if (map)
1086
 
                                radeon_teximage_map(image, GL_TRUE);
1087
 
                        else
1088
 
                                radeon_teximage_unmap(image);
1089
 
                }
1090
 
        }
1091
 
        
1092
 
        /* depth buffer (Note wrapper!) */
1093
 
        if (fb->_DepthBuffer)
1094
 
                map_unmap_rb(fb->_DepthBuffer->Wrapped, map);
1095
 
 
1096
 
        if (fb->_StencilBuffer)
1097
 
                map_unmap_rb(fb->_StencilBuffer->Wrapped, map);
1098
 
 
1099
 
        radeon_check_front_buffer_rendering(ctx);
1100
 
}
1101
 
 
1102
 
static void radeonSpanRenderStart(struct gl_context * ctx)
1103
 
{
1104
 
        radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1105
 
        int i;
1106
 
 
1107
 
        radeon_firevertices(rmesa);
1108
 
 
1109
 
        /* The locking and wait for idle should really only be needed in classic mode.
1110
 
         * In a future memory manager based implementation, this should become
1111
 
         * unnecessary due to the fact that mapping our buffers, textures, etc.
1112
 
         * should implicitly wait for any previous rendering commands that must
1113
 
         * be waited on. */
1114
 
        if (!rmesa->radeonScreen->driScreen->dri2.enabled) {
1115
 
                LOCK_HARDWARE(rmesa);
1116
 
                radeonWaitForIdleLocked(rmesa);
1117
 
        }
1118
 
 
1119
 
        for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
1120
 
                if (ctx->Texture.Unit[i]._ReallyEnabled)
1121
 
                        ctx->Driver.MapTexture(ctx, ctx->Texture.Unit[i]._Current);
1122
 
        }
1123
 
 
1124
 
        radeon_map_unmap_framebuffer(ctx, ctx->DrawBuffer, GL_TRUE);
1125
 
        if (ctx->ReadBuffer != ctx->DrawBuffer)
1126
 
                radeon_map_unmap_framebuffer(ctx, ctx->ReadBuffer, GL_TRUE);
1127
 
}
1128
 
 
1129
 
static void radeonSpanRenderFinish(struct gl_context * ctx)
1130
 
{
1131
 
        radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
1132
 
        int i;
1133
 
 
1134
 
        _swrast_flush(ctx);
1135
 
 
1136
 
        for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
1137
 
                if (ctx->Texture.Unit[i]._ReallyEnabled)
1138
 
                        ctx->Driver.UnmapTexture(ctx, ctx->Texture.Unit[i]._Current);
1139
 
        }
1140
 
 
1141
 
        radeon_map_unmap_framebuffer(ctx, ctx->DrawBuffer, GL_FALSE);
1142
 
        if (ctx->ReadBuffer != ctx->DrawBuffer)
1143
 
                radeon_map_unmap_framebuffer(ctx, ctx->ReadBuffer, GL_FALSE);
1144
 
 
1145
 
        if (!rmesa->radeonScreen->driScreen->dri2.enabled) {
1146
 
                UNLOCK_HARDWARE(rmesa);
1147
 
        }
1148
 
}
1149
 
 
1150
 
void radeonInitSpanFuncs(struct gl_context * ctx)
1151
 
{
1152
 
        struct swrast_device_driver *swdd =
1153
 
            _swrast_GetDeviceDriverReference(ctx);
1154
 
        swdd->SpanRenderStart = radeonSpanRenderStart;
1155
 
        swdd->SpanRenderFinish = radeonSpanRenderFinish;
1156
 
}
1157
 
 
1158
 
/**
1159
 
 * Plug in the Get/Put routines for the given driRenderbuffer.
1160
 
 */
1161
 
static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb)
1162
 
{
1163
 
        if (rrb->base.Format == MESA_FORMAT_RGB565) {
1164
 
                radeonInitPointers_RGB565(&rrb->base);
1165
 
        } else if (rrb->base.Format == MESA_FORMAT_RGB565_REV) {
1166
 
                radeonInitPointers_RGB565_REV(&rrb->base);
1167
 
        } else if (rrb->base.Format == MESA_FORMAT_XRGB8888) {
1168
 
                radeonInitPointers_xRGB8888(&rrb->base);
1169
 
        } else if (rrb->base.Format == MESA_FORMAT_XRGB8888_REV) {
1170
 
                radeonInitPointers_BGRx8888(&rrb->base);
1171
 
        } else if (rrb->base.Format == MESA_FORMAT_ARGB8888) {
1172
 
                radeonInitPointers_ARGB8888(&rrb->base);
1173
 
        } else if (rrb->base.Format == MESA_FORMAT_ARGB8888_REV) {
1174
 
                radeonInitPointers_BGRA8888(&rrb->base);
1175
 
        } else if (rrb->base.Format == MESA_FORMAT_ARGB4444) {
1176
 
                radeonInitPointers_ARGB4444(&rrb->base);
1177
 
        } else if (rrb->base.Format == MESA_FORMAT_ARGB4444_REV) {
1178
 
                radeonInitPointers_ARGB4444_REV(&rrb->base);
1179
 
        } else if (rrb->base.Format == MESA_FORMAT_ARGB1555) {
1180
 
                radeonInitPointers_ARGB1555(&rrb->base);
1181
 
        } else if (rrb->base.Format == MESA_FORMAT_ARGB1555_REV) {
1182
 
                radeonInitPointers_ARGB1555_REV(&rrb->base);
1183
 
        } else if (rrb->base.Format == MESA_FORMAT_Z16) {
1184
 
                radeonInitDepthPointers_z16(&rrb->base);
1185
 
        } else if (rrb->base.Format == MESA_FORMAT_X8_Z24) {
1186
 
                radeonInitDepthPointers_z24(&rrb->base);
1187
 
        } else if (rrb->base.Format == MESA_FORMAT_S8_Z24) {
1188
 
                radeonInitDepthPointers_s8_z24(&rrb->base);
1189
 
        } else if (rrb->base.Format == MESA_FORMAT_S8) {
1190
 
                radeonInitStencilPointers_s8_z24(&rrb->base);
1191
 
        } else {
1192
 
                fprintf(stderr, "radeonSetSpanFunctions: bad format: 0x%04X\n", rrb->base.Format);
1193
 
        }
1194
 
}