radeon_span.c revision f7bab47e6c7cf877acf6d9bb85453851e5aa7f19
1/**************************************************************************
2
3Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
4Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5                     VA Linux Systems Inc., Fremont, California.
6
7The Weather Channel (TM) funded Tungsten Graphics to develop the
8initial release of the Radeon 8500 driver under the XFree86 license.
9This notice must be preserved.
10
11All Rights Reserved.
12
13Permission is hereby granted, free of charge, to any person obtaining
14a copy of this software and associated documentation files (the
15"Software"), to deal in the Software without restriction, including
16without limitation the rights to use, copy, modify, merge, publish,
17distribute, sublicense, and/or sell copies of the Software, and to
18permit persons to whom the Software is furnished to do so, subject to
19the following conditions:
20
21The above copyright notice and this permission notice (including the
22next paragraph) shall be included in all copies or substantial
23portions of the Software.
24
25THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
28IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
29LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31WITH 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
53static 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)
60static GLubyte *r200_depth_2byte(const struct radeon_renderbuffer * rrb,
61				 GLint x, GLint y)
62{
63    GLubyte *ptr = rrb->bo->ptr + rrb->draw_offset;
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
85static GLubyte *r200_depth_4byte(const struct radeon_renderbuffer * rrb,
86				 GLint x, GLint y)
87{
88    GLubyte *ptr = rrb->bo->ptr + rrb->draw_offset;
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)
116static 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
210static inline GLint r600_log2(GLint n)
211{
212	GLint log2 = 0;
213
214	while (n >>= 1)
215		++log2;
216	return log2;
217}
218
219static 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 */
385static 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
397static 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
409static 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*/
439static GLubyte *radeon_ptr_4byte(const struct radeon_renderbuffer * rrb,
440			     GLint x, GLint y)
441{
442    GLubyte *ptr = rrb->bo->ptr + rrb->draw_offset;
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
479static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
480				     GLint x, GLint y)
481{
482    GLubyte *ptr = rrb->bo->ptr + rrb->draw_offset;
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 )					\
784do {									\
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 )					\
793do {									\
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 )					\
802do {									\
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 )					\
811do {									\
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 )					\
853do {									\
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 )					\
859do {									\
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 )					\
873do {									\
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 )					\
879do {									\
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 )					\
919do {									\
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 )					\
928do {									\
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 )					\
937do {									\
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 )					\
946do {									\
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 )					\
957do {									\
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 )					\
964do {									\
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 )					\
971do {									\
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 )					\
978do {									\
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
989static 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
1017static void
1018radeon_map_unmap_framebuffer(struct gl_context *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
1063static void radeonSpanRenderStart(struct gl_context * 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
1090static void radeonSpanRenderFinish(struct gl_context * 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
1111void radeonInitSpanFuncs(struct gl_context * 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 */
1122static 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}
1156