1 /**************************************************************************
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.
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.
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:
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.
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.
33 **************************************************************************/
37 * Kevin E. Martin <martin@valinux.com>
38 * Gareth Hughes <gareth@valinux.com>
39 * Keith Whitwell <keith@tungstengraphics.com>
43 #include "main/glheader.h"
44 #include "main/texformat.h"
45 #include "swrast/swrast.h"
47 #include "radeon_common.h"
48 #include "radeon_lock.h"
49 #include "radeon_span.h"
53 #if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
54 #if defined(__linux__)
56 #define CPU_TO_LE16( x ) bswap_16( x )
57 #define LE16_TO_CPU( x ) bswap_16( x )
58 #endif /* __linux__ */
60 #define CPU_TO_LE16( x ) ( x )
61 #define LE16_TO_CPU( x ) ( x )
64 static void radeonSetSpanFunctions(struct radeon_renderbuffer
*rrb
);
67 /* r200 depth buffer is always tiled - this is the formula
68 according to the docs unless I typo'ed in it
70 #if defined(RADEON_R200)
71 static GLubyte
*r200_depth_2byte(const struct radeon_renderbuffer
* rrb
,
74 GLubyte
*ptr
= rrb
->bo
->ptr
+ rrb
->draw_offset
;
76 if (rrb
->has_surface
) {
77 offset
= x
* rrb
->cpp
+ y
* rrb
->pitch
;
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;
96 static GLubyte
*r200_depth_4byte(const struct radeon_renderbuffer
* rrb
,
99 GLubyte
*ptr
= rrb
->bo
->ptr
+ rrb
->draw_offset
;
101 if (rrb
->has_surface
) {
102 offset
= x
* rrb
->cpp
+ y
* rrb
->pitch
;
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;
123 * - 1D (akin to macro-linear/micro-tiled on older asics)
124 * - 2D (akin to macro-tiled/micro-tiled on older asics)
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
)
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
;
138 GLint sample_number
= 0;
142 GLint tiles_per_slice
;
144 GLint tile_row_index
;
145 GLint tile_column_index
;
147 GLint pixel_number
= 0;
148 GLint element_offset
;
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
;
160 GLint pixel_offset
= 0;
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
) {
170 pixel_offset
= pixel_number
* element_bytes
* num_samples
;
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.
179 pixel_offset
= pixel_number
* 1 * num_samples
;
181 pixel_offset
= (pixel_number
* 3 * num_samples
) + 64;
184 element_offset
= pixel_offset
+ (sample_number
* element_bytes
);
188 switch (element_bytes
) {
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]
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]
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]
214 sample_offset
= sample_number
* (tile_bytes
/ num_samples
);
215 element_offset
= sample_offset
+ (pixel_number
* element_bytes
);
217 offset
= slice_offset
+ tile_offset
+ element_offset
;
221 static inline GLint
r600_log2(GLint n
)
230 static inline GLint
r600_2d_tile_helper(const struct radeon_renderbuffer
* rrb
,
231 GLint x
, GLint y
, GLint is_depth
, GLint is_stencil
)
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
;
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
;
251 GLint sample_number
= 0;
254 GLint macro_tile_bytes
;
255 GLint macro_tiles_per_row
;
256 GLint macro_tiles_per_slice
;
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
;
266 GLint group_mask
= (1 << group_bits
) - 1;
271 switch (num_channels
) {
274 // channel[0] = x[3] ^ y[3]
275 channel
|= (((x
>> 3) ^ (y
>> 3)) & 1) << 0;
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;
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;
295 // bank[0] = x[3] ^ y[4 + log2(num_channels)]
296 bank
|= (((x
>> 3) ^ (y
>> (4 + channel_bits
))) & 1) << 0;
298 // bank[1] = x[3] ^ y[4 + log2(num_channels)] ^ x[5]
299 bank
|= (((x
>> 4) ^ (y
>> (3 + channel_bits
)) ^ (x
>> 5)) & 1) << 1;
301 // bank[1] = x[4] ^ y[3 + log2(num_channels)]
302 bank
|= (((x
>> 4) ^ (y
>> (3 + channel_bits
))) & 1) << 1;
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;
310 // bank[2] = x[5] ^ y[3 + log2(num_channels)] ^ x[6]
311 bank
|= (((x
>> 5) ^ (y
>> (3 + channel_bits
)) ^ (x
>> 6)) & 1) << 2;
313 // bank[2] = x[5] ^ y[3 + log2(num_channels)]
314 bank
|= (((x
>> 5) ^ (y
>> (3 + channel_bits
))) & 1) << 2;
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
;
328 GLint pixel_offset
= 0;
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
) {
338 pixel_offset
= pixel_number
* element_bytes
* num_samples
;
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.
347 pixel_offset
= pixel_number
* 1 * num_samples
;
349 pixel_offset
= (pixel_number
* 3 * num_samples
) + 64;
352 element_offset
= pixel_offset
+ (sample_number
* element_bytes
);
356 switch (element_bytes
) {
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]
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]
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]
382 sample_offset
= sample_number
* (tile_bytes
/ num_samples
);
383 element_offset
= sample_offset
+ (pixel_number
* element_bytes
);
385 total_offset
= (slice_offset
+ macro_tile_offset
) >> (channel_bits
+ bank_bits
);
386 total_offset
+= element_offset
;
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
;
396 static GLubyte
*r600_ptr_depth(const struct radeon_renderbuffer
* rrb
,
399 GLubyte
*ptr
= rrb
->bo
->ptr
;
401 if (rrb
->bo
->flags
& RADEON_BO_FLAGS_MACRO_TILE
)
402 offset
= r600_2d_tile_helper(rrb
, x
, y
, 1, 0);
404 offset
= r600_1d_tile_helper(rrb
, x
, y
, 1, 0);
408 static GLubyte
*r600_ptr_stencil(const struct radeon_renderbuffer
* rrb
,
411 GLubyte
*ptr
= rrb
->bo
->ptr
;
413 if (rrb
->bo
->flags
& RADEON_BO_FLAGS_MACRO_TILE
)
414 offset
= r600_2d_tile_helper(rrb
, x
, y
, 1, 1);
416 offset
= r600_1d_tile_helper(rrb
, x
, y
, 1, 1);
420 static GLubyte
*r600_ptr_color(const struct radeon_renderbuffer
* rrb
,
423 GLubyte
*ptr
= rrb
->bo
->ptr
;
424 uint32_t mask
= RADEON_BO_FLAGS_MACRO_TILE
| RADEON_BO_FLAGS_MICRO_TILE
;
427 if (rrb
->has_surface
|| !(rrb
->bo
->flags
& mask
)) {
428 offset
= x
* rrb
->cpp
+ y
* rrb
->pitch
;
430 if (rrb
->bo
->flags
& RADEON_BO_FLAGS_MACRO_TILE
)
431 offset
= r600_2d_tile_helper(rrb
, x
, y
, 0, 0);
433 offset
= r600_1d_tile_helper(rrb
, x
, y
, 0, 0);
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
446 2 byte surface - two types - we only provide 8x2 microtiling
450 static GLubyte
*radeon_ptr_4byte(const struct radeon_renderbuffer
* rrb
,
453 GLubyte
*ptr
= rrb
->bo
->ptr
+ rrb
->draw_offset
;
454 uint32_t mask
= RADEON_BO_FLAGS_MACRO_TILE
| RADEON_BO_FLAGS_MICRO_TILE
;
457 if (rrb
->has_surface
|| !(rrb
->bo
->flags
& mask
)) {
458 offset
= x
* rrb
->cpp
+ y
* rrb
->pitch
;
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;
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;
482 offset
= ((y
>> 1) * (rrb
->pitch
>> 4) + (x
>> 2)) << 5;
483 offset
+= (y
& 1) << 4;
484 offset
+= (x
& 3) << 2;
490 static GLubyte
*radeon_ptr_2byte_8x2(const struct radeon_renderbuffer
* rrb
,
493 GLubyte
*ptr
= rrb
->bo
->ptr
+ rrb
->draw_offset
;
494 uint32_t mask
= RADEON_BO_FLAGS_MACRO_TILE
| RADEON_BO_FLAGS_MICRO_TILE
;
497 if (rrb
->has_surface
|| !(rrb
->bo
->flags
& mask
)) {
498 offset
= x
* rrb
->cpp
+ y
* rrb
->pitch
;
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;
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;
523 offset
= ((y
>> 1) * (rrb
->pitch
>> 4) + (x
>> 3)) << 5;
524 offset
+= (y
& 0x1) << 4;
525 offset
+= (x
& 0x7) << 1;
534 * Note that all information needed to access pixels in a renderbuffer
535 * should be obtained through the gl_renderbuffer parameter, not per-context
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; \
548 radeon_get_cliprects(radeon, &cliprects, &num_cliprects, &x_off, &y_off);
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; \
558 radeon_get_cliprects(radeon, &cliprects, &num_cliprects, &x_off, &y_off);
560 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
562 #define Y_FLIP(_y) ((_y) * yScale + yBias)
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.
572 #define HW_CLIPLOOP() \
574 int _nc = num_cliprects; \
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;
581 /* ================================================================
585 /* 16 bit, RGB565 color spanline and pixel functions
587 #define SPANTMP_PIXEL_FMT GL_RGB
588 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
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); \
599 #define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off)
601 #include "spantmp2.h"
603 #define SPANTMP_PIXEL_FMT GL_RGB
604 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5_REV
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); \
615 #define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off)
617 #include "spantmp2.h"
619 /* 16 bit, ARGB1555 color spanline and pixel functions
621 #define SPANTMP_PIXEL_FMT GL_BGRA
622 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5_REV
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); \
633 #define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off)
635 #include "spantmp2.h"
637 #define SPANTMP_PIXEL_FMT GL_BGRA
638 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5
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); \
649 #define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off)
651 #include "spantmp2.h"
653 /* 16 bit, RGBA4 color spanline and pixel functions
655 #define SPANTMP_PIXEL_FMT GL_BGRA
656 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4_REV
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); \
667 #define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off)
669 #include "spantmp2.h"
671 #define SPANTMP_PIXEL_FMT GL_BGRA
672 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4
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); \
683 #define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off)
685 #include "spantmp2.h"
687 /* 32 bit, xRGB8888 color spanline and pixel functions
689 #define SPANTMP_PIXEL_FMT GL_BGRA
690 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
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); \
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 ); \
707 #include "spantmp2.h"
709 /* 32 bit, ARGB8888 color spanline and pixel functions
711 #define SPANTMP_PIXEL_FMT GL_BGRA
712 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
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); \
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 ); \
729 #include "spantmp2.h"
731 /* 32 bit, BGRx8888 color spanline and pixel functions
733 #define SPANTMP_PIXEL_FMT GL_BGRA
734 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8
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); \
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 ); \
751 #include "spantmp2.h"
753 /* 32 bit, BGRA8888 color spanline and pixel functions
755 #define SPANTMP_PIXEL_FMT GL_BGRA
756 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8
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); \
767 #define GET_PTR(X,Y) radeon_ptr_4byte(rrb, (X) + x_off, (Y) + y_off)
769 #include "spantmp2.h"
771 /* ================================================================
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
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
785 /* 16-bit depth buffer functions
787 #define VALUE_TYPE GLushort
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)
796 #define WRITE_DEPTH( _x, _y, d ) \
797 *(GLushort *)radeon_ptr_2byte_8x2(rrb, _x + x_off, _y + y_off) = d
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))
807 #define READ_DEPTH( d, _x, _y ) \
808 d = *(GLushort *)radeon_ptr_2byte_8x2(rrb, _x + x_off, _y + y_off)
811 #define TAG(x) radeon##x##_z16
812 #include "depthtmp.h"
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.
819 #define VALUE_TYPE GLuint
821 #if defined(RADEON_R300)
822 #define WRITE_DEPTH( _x, _y, d ) \
824 GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \
825 GLuint tmp = LE32_TO_CPU(*_ptr); \
827 tmp |= ((d << 8) & 0xffffff00); \
828 *_ptr = CPU_TO_LE32(tmp); \
830 #elif defined(RADEON_R600)
831 #define WRITE_DEPTH( _x, _y, d ) \
833 GLuint *_ptr = (GLuint*)r600_ptr_depth( rrb, _x + x_off, _y + y_off ); \
834 GLuint tmp = LE32_TO_CPU(*_ptr); \
836 tmp |= ((d) & 0x00ffffff); \
837 *_ptr = CPU_TO_LE32(tmp); \
839 #elif defined(RADEON_R200)
840 #define WRITE_DEPTH( _x, _y, d ) \
842 GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x + x_off, _y + y_off ); \
843 GLuint tmp = LE32_TO_CPU(*_ptr); \
845 tmp |= ((d) & 0x00ffffff); \
846 *_ptr = CPU_TO_LE32(tmp); \
849 #define WRITE_DEPTH( _x, _y, d ) \
851 GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \
852 GLuint tmp = LE32_TO_CPU(*_ptr); \
854 tmp |= ((d) & 0x00ffffff); \
855 *_ptr = CPU_TO_LE32(tmp); \
859 #if defined(RADEON_R300)
860 #define READ_DEPTH( d, _x, _y ) \
862 d = (LE32_TO_CPU(*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off))) & 0xffffff00) >> 8; \
864 #elif defined(RADEON_R600)
865 #define READ_DEPTH( d, _x, _y ) \
867 d = (LE32_TO_CPU(*(GLuint*)(r600_ptr_depth(rrb, _x + x_off, _y + y_off))) & 0x00ffffff); \
869 #elif defined(RADEON_R200)
870 #define READ_DEPTH( d, _x, _y ) \
872 d = LE32_TO_CPU(*(GLuint*)(r200_depth_4byte(rrb, _x + x_off, _y + y_off))) & 0x00ffffff; \
875 #define READ_DEPTH( d, _x, _y ) \
876 d = LE32_TO_CPU(*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off))) & 0x00ffffff;
879 #define TAG(x) radeon##x##_z24
880 #include "depthtmp.h"
882 /* 24 bit depth, 8 bit stencil depthbuffer functions
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.
888 #define VALUE_TYPE GLuint
890 #if defined(RADEON_R300)
891 #define WRITE_DEPTH( _x, _y, d ) \
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)); \
896 #elif defined(RADEON_R600)
897 #define WRITE_DEPTH( _x, _y, d ) \
899 GLuint *_ptr = (GLuint*)r600_ptr_depth( rrb, _x + x_off, _y + y_off ); \
900 GLuint tmp = LE32_TO_CPU(*_ptr); \
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); \
907 tmp |= ((d) >> 24) & 0xff; \
908 *_ptr = CPU_TO_LE32(tmp); \
910 #elif defined(RADEON_R200)
911 #define WRITE_DEPTH( _x, _y, d ) \
913 GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x + x_off, _y + y_off ); \
914 *_ptr = CPU_TO_LE32(d); \
917 #define WRITE_DEPTH( _x, _y, d ) \
919 GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \
920 *_ptr = CPU_TO_LE32(d); \
924 #if defined(RADEON_R300)
925 #define READ_DEPTH( d, _x, _y ) \
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)); \
930 #elif defined(RADEON_R600)
931 #define READ_DEPTH( d, _x, _y ) \
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); \
936 #elif defined(RADEON_R200)
937 #define READ_DEPTH( d, _x, _y ) \
939 d = LE32_TO_CPU(*(GLuint*)(r200_depth_4byte(rrb, _x + x_off, _y + y_off))); \
942 #define READ_DEPTH( d, _x, _y ) do { \
943 d = LE32_TO_CPU(*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off))); \
947 #define TAG(x) radeon##x##_s8_z24
948 #include "depthtmp.h"
950 /* ================================================================
954 /* 24 bit depth, 8 bit stencil depthbuffer functions
957 #define WRITE_STENCIL( _x, _y, d ) \
959 GLuint *_ptr = (GLuint*)radeon_ptr_4byte(rrb, _x + x_off, _y + y_off); \
960 GLuint tmp = LE32_TO_CPU(*_ptr); \
963 *_ptr = CPU_TO_LE32(tmp); \
965 #elif defined(RADEON_R600)
966 #define WRITE_STENCIL( _x, _y, d ) \
968 GLuint *_ptr = (GLuint*)r600_ptr_stencil(rrb, _x + x_off, _y + y_off); \
969 GLuint tmp = LE32_TO_CPU(*_ptr); \
972 *_ptr = CPU_TO_LE32(tmp); \
974 #elif defined(RADEON_R200)
975 #define WRITE_STENCIL( _x, _y, d ) \
977 GLuint *_ptr = (GLuint*)r200_depth_4byte(rrb, _x + x_off, _y + y_off); \
978 GLuint tmp = LE32_TO_CPU(*_ptr); \
980 tmp |= (((d) & 0xff) << 24); \
981 *_ptr = CPU_TO_LE32(tmp); \
984 #define WRITE_STENCIL( _x, _y, d ) \
986 GLuint *_ptr = (GLuint*)radeon_ptr_4byte(rrb, _x + x_off, _y + y_off); \
987 GLuint tmp = LE32_TO_CPU(*_ptr); \
989 tmp |= (((d) & 0xff) << 24); \
990 *_ptr = CPU_TO_LE32(tmp); \
995 #define READ_STENCIL( d, _x, _y ) \
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; \
1001 #elif defined(RADEON_R600)
1002 #define READ_STENCIL( d, _x, _y ) \
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; \
1008 #elif defined(RADEON_R200)
1009 #define READ_STENCIL( d, _x, _y ) \
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; \
1016 #define READ_STENCIL( d, _x, _y ) \
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; \
1024 #define TAG(x) radeon##x##_s8_z24
1025 #include "stenciltmp.h"
1028 static void map_unmap_rb(struct gl_renderbuffer
*rb
, int flag
)
1030 struct radeon_renderbuffer
*rrb
= radeon_renderbuffer(rb
);
1033 if (rrb
== NULL
|| !rrb
->bo
)
1036 radeon_print(RADEON_MEMORY
, RADEON_TRACE
,
1037 "%s( rb %p, flag %s )\n",
1038 __func__
, rb
, flag
? "true":"false");
1041 radeon_bo_wait(rrb
->bo
);
1042 r
= radeon_bo_map(rrb
->bo
, 1);
1044 fprintf(stderr
, "(%s) error(%d) mapping buffer.\n",
1048 radeonSetSpanFunctions(rrb
);
1050 radeon_bo_unmap(rrb
->bo
);
1057 radeon_map_unmap_framebuffer(struct gl_context
*ctx
, struct gl_framebuffer
*fb
,
1062 radeon_print(RADEON_MEMORY
, RADEON_TRACE
,
1063 "%s( %p , fb %p, map %s )\n",
1064 __func__
, ctx
, fb
, map
? "true":"false");
1066 /* color draw buffers */
1067 for (j
= 0; j
< ctx
->DrawBuffer
->_NumColorDrawBuffers
; j
++)
1068 map_unmap_rb(fb
->_ColorDrawBuffers
[j
], map
);
1070 map_unmap_rb(fb
->_ColorReadBuffer
, map
);
1072 /* check for render to textures */
1073 for (i
= 0; i
< BUFFER_COUNT
; i
++) {
1074 struct gl_renderbuffer_attachment
*att
=
1076 struct gl_texture_object
*tex
= att
->Texture
;
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.
1082 radeon_texture_image
*image
= get_radeon_texture_image(tex
->Image
[att
->CubeMapFace
][att
->TextureLevel
]);
1083 ASSERT(att
->Renderbuffer
);
1086 radeon_teximage_map(image
, GL_TRUE
);
1088 radeon_teximage_unmap(image
);
1092 /* depth buffer (Note wrapper!) */
1093 if (fb
->_DepthBuffer
)
1094 map_unmap_rb(fb
->_DepthBuffer
->Wrapped
, map
);
1096 if (fb
->_StencilBuffer
)
1097 map_unmap_rb(fb
->_StencilBuffer
->Wrapped
, map
);
1099 radeon_check_front_buffer_rendering(ctx
);
1102 static void radeonSpanRenderStart(struct gl_context
* ctx
)
1104 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
1107 radeon_firevertices(rmesa
);
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
1114 if (!rmesa
->radeonScreen
->driScreen
->dri2
.enabled
) {
1115 LOCK_HARDWARE(rmesa
);
1116 radeonWaitForIdleLocked(rmesa
);
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
);
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
);
1129 static void radeonSpanRenderFinish(struct gl_context
* ctx
)
1131 radeonContextPtr rmesa
= RADEON_CONTEXT(ctx
);
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
);
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
);
1145 if (!rmesa
->radeonScreen
->driScreen
->dri2
.enabled
) {
1146 UNLOCK_HARDWARE(rmesa
);
1150 void radeonInitSpanFuncs(struct gl_context
* ctx
)
1152 struct swrast_device_driver
*swdd
=
1153 _swrast_GetDeviceDriverReference(ctx
);
1154 swdd
->SpanRenderStart
= radeonSpanRenderStart
;
1155 swdd
->SpanRenderFinish
= radeonSpanRenderFinish
;
1159 * Plug in the Get/Put routines for the given driRenderbuffer.
1161 static void radeonSetSpanFunctions(struct radeon_renderbuffer
*rrb
)
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
);
1192 fprintf(stderr
, "radeonSetSpanFunctions: bad format: 0x%04X\n", rrb
->base
.Format
);