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