radeon_span.c revision b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9
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_span.h"
49
50#define DBG 0
51
52#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
53#if defined(__linux__)
54#include <byteswap.h>
55#define CPU_TO_LE16( x )	bswap_16( x )
56#define LE16_TO_CPU( x )	bswap_16( x )
57#endif /* __linux__ */
58#else
59#define CPU_TO_LE16( x )	( x )
60#define LE16_TO_CPU( x )	( x )
61#endif
62
63static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb);
64
65
66/* r200 depth buffer is always tiled - this is the formula
67   according to the docs unless I typo'ed in it
68*/
69#if defined(RADEON_R200)
70static GLubyte *r200_depth_2byte(const struct radeon_renderbuffer * rrb,
71				 GLint x, GLint y)
72{
73    GLubyte *ptr = rrb->bo->ptr + rrb->draw_offset;
74    GLint offset;
75    if (rrb->has_surface) {
76	offset = x * rrb->cpp + y * rrb->pitch;
77    } else {
78	GLuint b;
79	offset = 0;
80	b = (((y  >> 4) * (rrb->pitch >> 8) + (x >> 6)));
81	offset += (b >> 1) << 12;
82	offset += (((rrb->pitch >> 8) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11;
83	offset += ((y >> 2) & 0x3) << 9;
84	offset += ((x >> 3) & 0x1) << 8;
85	offset += ((x >> 4) & 0x3) << 6;
86	offset += ((x >> 2) & 0x1) << 5;
87	offset += ((y >> 1) & 0x1) << 4;
88	offset += ((x >> 1) & 0x1) << 3;
89	offset += (y & 0x1) << 2;
90	offset += (x & 0x1) << 1;
91    }
92    return &ptr[offset];
93}
94
95static GLubyte *r200_depth_4byte(const struct radeon_renderbuffer * rrb,
96				 GLint x, GLint y)
97{
98    GLubyte *ptr = rrb->bo->ptr + rrb->draw_offset;
99    GLint offset;
100    if (rrb->has_surface) {
101	offset = x * rrb->cpp + y * rrb->pitch;
102    } else {
103	GLuint b;
104	offset = 0;
105	b = (((y & 0x7ff) >> 4) * (rrb->pitch >> 7) + (x >> 5));
106	offset += (b >> 1) << 12;
107	offset += (((rrb->pitch >> 7) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11;
108	offset += ((y >> 2) & 0x3) << 9;
109	offset += ((x >> 2) & 0x1) << 8;
110	offset += ((x >> 3) & 0x3) << 6;
111	offset += ((y >> 1) & 0x1) << 5;
112	offset += ((x >> 1) & 0x1) << 4;
113	offset += (y & 0x1) << 3;
114	offset += (x & 0x1) << 2;
115    }
116    return &ptr[offset];
117}
118#endif
119
120
121/* radeon tiling on r300-r500 has 4 states,
122   macro-linear/micro-linear
123   macro-linear/micro-tiled
124   macro-tiled /micro-linear
125   macro-tiled /micro-tiled
126   1 byte surface
127   2 byte surface - two types - we only provide 8x2 microtiling
128   4 byte surface
129   8/16 byte (unused)
130*/
131static GLubyte *radeon_ptr_4byte(const struct radeon_renderbuffer * rrb,
132			     GLint x, GLint y)
133{
134    GLubyte *ptr = rrb->bo->ptr + rrb->draw_offset;
135    uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE;
136    GLint offset;
137
138    if (rrb->has_surface || !(rrb->bo->flags & mask)) {
139        offset = x * rrb->cpp + y * rrb->pitch;
140    } else {
141        offset = 0;
142        if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) {
143	    if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) {
144		offset = ((y >> 4) * (rrb->pitch >> 7) + (x >> 5)) << 11;
145		offset += (((y >> 3) ^ (x >> 5)) & 0x1) << 10;
146		offset += (((y >> 4) ^ (x >> 4)) & 0x1) << 9;
147		offset += (((y >> 2) ^ (x >> 4)) & 0x1) << 8;
148		offset += (((y >> 3) ^ (x >> 3)) & 0x1) << 7;
149		offset += ((y >> 1) & 0x1) << 6;
150		offset += ((x >> 2) & 0x1) << 5;
151		offset += (y & 1) << 4;
152		offset += (x & 3) << 2;
153            } else {
154		offset = ((y >> 3) * (rrb->pitch >> 8) + (x >> 6)) << 11;
155		offset += (((y >> 2) ^ (x >> 6)) & 0x1) << 10;
156		offset += (((y >> 3) ^ (x >> 5)) & 0x1) << 9;
157		offset += (((y >> 1) ^ (x >> 5)) & 0x1) << 8;
158		offset += (((y >> 2) ^ (x >> 4)) & 0x1) << 7;
159		offset += (y & 1) << 6;
160		offset += (x & 15) << 2;
161            }
162        } else {
163	    offset = ((y >> 1) * (rrb->pitch >> 4) + (x >> 2)) << 5;
164	    offset += (y & 1) << 4;
165	    offset += (x & 3) << 2;
166        }
167    }
168    return &ptr[offset];
169}
170
171static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
172				     GLint x, GLint y)
173{
174    GLubyte *ptr = rrb->bo->ptr + rrb->draw_offset;
175    uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE;
176    GLint offset;
177
178    if (rrb->has_surface || !(rrb->bo->flags & mask)) {
179        offset = x * rrb->cpp + y * rrb->pitch;
180    } else {
181        offset = 0;
182        if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) {
183            if (rrb->bo->flags & RADEON_BO_FLAGS_MICRO_TILE) {
184		offset = ((y >> 4) * (rrb->pitch >> 7) + (x >> 6)) << 11;
185		offset += (((y >> 3) ^ (x >> 6)) & 0x1) << 10;
186		offset += (((y >> 4) ^ (x >> 5)) & 0x1) << 9;
187		offset += (((y >> 2) ^ (x >> 5)) & 0x1) << 8;
188		offset += (((y >> 3) ^ (x >> 4)) & 0x1) << 7;
189		offset += ((y >> 1) & 0x1) << 6;
190		offset += ((x >> 3) & 0x1) << 5;
191		offset += (y & 1) << 4;
192		offset += (x & 3) << 2;
193            } else {
194		offset = ((y >> 3) * (rrb->pitch >> 8) + (x >> 7)) << 11;
195		offset += (((y >> 2) ^ (x >> 7)) & 0x1) << 10;
196		offset += (((y >> 3) ^ (x >> 6)) & 0x1) << 9;
197		offset += (((y >> 1) ^ (x >> 6)) & 0x1) << 8;
198		offset += (((y >> 2) ^ (x >> 5)) & 0x1) << 7;
199		offset += (y & 1) << 6;
200		offset += ((x >> 4) & 0x1) << 5;
201                offset += (x & 15) << 2;
202            }
203        } else {
204	    offset = ((y >> 1) * (rrb->pitch >> 4) + (x >> 3)) << 5;
205	    offset += (y & 0x1) << 4;
206	    offset += (x & 0x7) << 1;
207        }
208    }
209    return &ptr[offset];
210}
211
212/*
213 * Note that all information needed to access pixels in a renderbuffer
214 * should be obtained through the gl_renderbuffer parameter, not per-context
215 * information.
216 */
217#define LOCAL_VARS						\
218   struct radeon_renderbuffer *rrb = (void *) rb;		\
219   int minx = 0, miny = 0;						\
220   int maxx = rb->Width;						\
221   int maxy = rb->Height;						\
222   void *buf = rb->Data;						\
223   int pitch = rb->RowStride * rrb->cpp;				\
224   GLuint p;						\
225   (void)p;
226
227#define LOCAL_DEPTH_VARS				\
228   struct radeon_renderbuffer *rrb = (void *) rb;	\
229   int minx = 0, miny = 0;						\
230   const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1;                 \
231   const GLint yBias = ctx->DrawBuffer->Name ? 0 : rrb->base.Height - 1; \
232   int maxx = rb->Width;						\
233   int maxy = rb->Height;
234
235#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
236
237#define Y_FLIP(_y) (_y)
238
239#define HW_LOCK()
240#define HW_UNLOCK()
241#define HW_CLIPLOOP()
242#define HW_ENDCLIPLOOP()
243
244/* ================================================================
245 * Color buffer
246 */
247
248/* 16 bit, RGB565 color spanline and pixel functions
249 */
250#define SPANTMP_PIXEL_FMT GL_RGB
251#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
252#define TAG(x)    radeon##x##_RGB565
253#define TAG2(x,y) radeon##x##_RGB565##y
254#include "spantmp2.h"
255
256#define SPANTMP_PIXEL_FMT GL_RGB
257#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5_REV
258#define TAG(x)    radeon##x##_RGB565_REV
259#define TAG2(x,y) radeon##x##_RGB565_REV##y
260#include "spantmp2.h"
261
262/* 16 bit, ARGB1555 color spanline and pixel functions
263 */
264#define SPANTMP_PIXEL_FMT GL_BGRA
265#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5_REV
266#define TAG(x)    radeon##x##_ARGB1555
267#define TAG2(x,y) radeon##x##_ARGB1555##y
268#include "spantmp2.h"
269
270#define SPANTMP_PIXEL_FMT GL_BGRA
271#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5
272#define TAG(x)    radeon##x##_ARGB1555_REV
273#define TAG2(x,y) radeon##x##_ARGB1555_REV##y
274#include "spantmp2.h"
275
276/* 16 bit, RGBA4 color spanline and pixel functions
277 */
278#define SPANTMP_PIXEL_FMT GL_BGRA
279#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4_REV
280#define TAG(x)    radeon##x##_ARGB4444
281#define TAG2(x,y) radeon##x##_ARGB4444##y
282#include "spantmp2.h"
283
284#define SPANTMP_PIXEL_FMT GL_BGRA
285#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4
286#define TAG(x)    radeon##x##_ARGB4444_REV
287#define TAG2(x,y) radeon##x##_ARGB4444_REV##y
288#include "spantmp2.h"
289
290/* 32 bit, xRGB8888 color spanline and pixel functions
291 */
292#define SPANTMP_PIXEL_FMT GL_BGRA
293#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
294#define TAG(x)    radeon##x##_xRGB8888
295#define TAG2(x,y) radeon##x##_xRGB8888##y
296#include "spantmp2.h"
297
298/* 32 bit, ARGB8888 color spanline and pixel functions
299 */
300#define SPANTMP_PIXEL_FMT GL_BGRA
301#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
302#define TAG(x)    radeon##x##_ARGB8888
303#define TAG2(x,y) radeon##x##_ARGB8888##y
304#include "spantmp2.h"
305
306/* 32 bit, BGRx8888 color spanline and pixel functions
307 */
308#define SPANTMP_PIXEL_FMT GL_BGRA
309#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8
310#define TAG(x)    radeon##x##_BGRx8888
311#define TAG2(x,y) radeon##x##_BGRx8888##y
312#include "spantmp2.h"
313
314/* 32 bit, BGRA8888 color spanline and pixel functions
315 */
316#define SPANTMP_PIXEL_FMT GL_BGRA
317#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8
318#define TAG(x)    radeon##x##_BGRA8888
319#define TAG2(x,y) radeon##x##_BGRA8888##y
320#include "spantmp2.h"
321
322#undef Y_FLIP
323#define Y_FLIP(_y) ((_y) * yScale + yBias)
324/* ================================================================
325 * Depth buffer
326 */
327
328/* The Radeon family has depth tiling on all the time, so we have to convert
329 * the x,y coordinates into the memory bus address (mba) in the same
330 * manner as the engine.  In each case, the linear block address (ba)
331 * is calculated, and then wired with x and y to produce the final
332 * memory address.
333 * The chip will do address translation on its own if the surface registers
334 * are set up correctly. It is not quite enough to get it working with hyperz
335 * too...
336 */
337
338/* 16-bit depth buffer functions
339 */
340#define VALUE_TYPE GLushort
341
342#if defined(RADEON_R200)
343#define WRITE_DEPTH( _x, _y, d )					\
344   *(GLushort *)r200_depth_2byte(rrb, _x, _y) = d
345#else
346#define WRITE_DEPTH( _x, _y, d )					\
347   *(GLushort *)radeon_ptr_2byte_8x2(rrb, _x, _y) = d
348#endif
349
350#if defined(RADEON_R200)
351#define READ_DEPTH( d, _x, _y )						\
352   d = *(GLushort *)r200_depth_2byte(rrb, _x, _y)
353#else
354#define READ_DEPTH( d, _x, _y )						\
355   d = *(GLushort *)radeon_ptr_2byte_8x2(rrb, _x, _y)
356#endif
357
358#define TAG(x) radeon##x##_z16
359#include "depthtmp.h"
360
361/* 24 bit depth
362 *
363 * Careful: It looks like the R300 uses ZZZS byte order while the R200
364 * uses SZZZ for 24 bit depth, 8 bit stencil mode.
365 */
366#define VALUE_TYPE GLuint
367
368#if defined(RADEON_R200)
369#define WRITE_DEPTH( _x, _y, d )					\
370do {									\
371   GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x, _y );		\
372   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
373   tmp &= 0xff000000;							\
374   tmp |= ((d) & 0x00ffffff);						\
375   *_ptr = CPU_TO_LE32(tmp);                                            \
376} while (0)
377#else
378#define WRITE_DEPTH( _x, _y, d )					\
379do {									\
380   GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x, _y );	\
381   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
382   tmp &= 0xff000000;							\
383   tmp |= ((d) & 0x00ffffff);						\
384   *_ptr = CPU_TO_LE32(tmp);                                            \
385} while (0)
386#endif
387
388#if defined(RADEON_R200)
389#define READ_DEPTH( d, _x, _y )						\
390  do {									\
391    d = LE32_TO_CPU(*(GLuint*)(r200_depth_4byte(rrb, _x, _y))) & 0x00ffffff; \
392  }while(0)
393#else
394#define READ_DEPTH( d, _x, _y )	\
395  d = LE32_TO_CPU(*(GLuint*)(radeon_ptr_4byte(rrb, _x,	_y))) & 0x00ffffff;
396#endif
397
398#define TAG(x) radeon##x##_z24
399#include "depthtmp.h"
400
401/* 24 bit depth, 8 bit stencil depthbuffer functions
402 * EXT_depth_stencil
403 *
404 * Careful: It looks like the R300 uses ZZZS byte order while the R200
405 * uses SZZZ for 24 bit depth, 8 bit stencil mode.
406 */
407#define VALUE_TYPE GLuint
408
409#if defined(RADEON_R200)
410#define WRITE_DEPTH( _x, _y, d )					\
411do {									\
412   GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x, _y );		\
413   *_ptr = CPU_TO_LE32(d);						\
414} while (0)
415#else
416#define WRITE_DEPTH( _x, _y, d )					\
417do {									\
418   GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x, _y );	\
419   *_ptr = CPU_TO_LE32(d);						\
420} while (0)
421#endif
422
423#if defined(RADEON_R200)
424#define READ_DEPTH( d, _x, _y )						\
425  do { \
426    d = LE32_TO_CPU(*(GLuint*)(r200_depth_4byte(rrb, _x, _y))); \
427  }while(0)
428#else
429#define READ_DEPTH( d, _x, _y )	do {					\
430    d = LE32_TO_CPU(*(GLuint*)(radeon_ptr_4byte(rrb, _x, _y))); \
431  } while (0)
432#endif
433
434#define TAG(x) radeon##x##_s8_z24
435#include "depthtmp.h"
436
437/* ================================================================
438 * Stencil buffer
439 */
440
441/* 24 bit depth, 8 bit stencil depthbuffer functions
442 */
443#if defined(RADEON_R200)
444#define WRITE_STENCIL( _x, _y, d )					\
445do {									\
446   GLuint *_ptr = (GLuint*)r200_depth_4byte(rrb, _x, _y);		\
447   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
448   tmp &= 0x00ffffff;							\
449   tmp |= (((d) & 0xff) << 24);						\
450   *_ptr = CPU_TO_LE32(tmp);                                            \
451} while (0)
452#else
453#define WRITE_STENCIL( _x, _y, d )					\
454do {									\
455   GLuint *_ptr = (GLuint*)radeon_ptr_4byte(rrb, _x, _y);		\
456   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
457   tmp &= 0x00ffffff;							\
458   tmp |= (((d) & 0xff) << 24);						\
459   *_ptr = CPU_TO_LE32(tmp);                                            \
460} while (0)
461#endif
462
463#if defined(RADEON_R200)
464#define READ_STENCIL( d, _x, _y )					\
465do {									\
466   GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x, _y );		\
467   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
468   d = (tmp & 0xff000000) >> 24;					\
469} while (0)
470#else
471#define READ_STENCIL( d, _x, _y )					\
472do {									\
473   GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x, _y );		\
474   GLuint tmp = LE32_TO_CPU(*_ptr);                                     \
475   d = (tmp & 0xff000000) >> 24;					\
476} while (0)
477#endif
478
479#define TAG(x) radeon##x##_s8_z24
480#include "stenciltmp.h"
481
482static void
483radeon_renderbuffer_map(struct gl_context *ctx, struct gl_renderbuffer *rb)
484{
485	struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
486	GLubyte *map;
487	int stride;
488
489	if (!rb || !rrb)
490		return;
491
492	ctx->Driver.MapRenderbuffer(ctx, rb, 0, 0, rb->Width, rb->Height,
493				    GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
494				    &map, &stride);
495
496	rb->Data = map;
497	rb->RowStride = stride / _mesa_get_format_bytes(rb->Format);
498
499	radeonSetSpanFunctions(rrb);
500}
501
502static void
503radeon_renderbuffer_unmap(struct gl_context *ctx, struct gl_renderbuffer *rb)
504{
505	struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
506	if (!rb || !rrb)
507		return;
508
509	ctx->Driver.UnmapRenderbuffer(ctx, rb);
510
511	rb->GetRow = NULL;
512	rb->PutRow = NULL;
513	rb->Data = NULL;
514	rb->RowStride = 0;
515}
516
517static void
518radeon_map_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
519{
520	GLuint i, j;
521
522	radeon_print(RADEON_MEMORY, RADEON_TRACE,
523		"%s( %p , fb %p )\n",
524		     __func__, ctx, fb);
525
526	/* check for render to textures */
527	for (i = 0; i < BUFFER_COUNT; i++)
528		radeon_renderbuffer_map(ctx, fb->Attachment[i].Renderbuffer);
529
530	radeon_check_front_buffer_rendering(ctx);
531}
532
533static void
534radeon_unmap_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
535{
536	GLuint i, j;
537
538	radeon_print(RADEON_MEMORY, RADEON_TRACE,
539		"%s( %p , fb %p)\n",
540		     __func__, ctx, fb);
541
542	/* check for render to textures */
543	for (i = 0; i < BUFFER_COUNT; i++)
544		radeon_renderbuffer_unmap(ctx, fb->Attachment[i].Renderbuffer);
545
546	radeon_check_front_buffer_rendering(ctx);
547}
548
549static void radeonSpanRenderStart(struct gl_context * ctx)
550{
551	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
552	int i;
553
554	radeon_firevertices(rmesa);
555
556	for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
557		if (ctx->Texture.Unit[i]._ReallyEnabled) {
558			radeon_validate_texture_miptree(ctx, ctx->Texture.Unit[i]._Current);
559			radeon_swrast_map_texture_images(ctx, ctx->Texture.Unit[i]._Current);
560		}
561	}
562
563	radeon_map_framebuffer(ctx, ctx->DrawBuffer);
564	if (ctx->ReadBuffer != ctx->DrawBuffer)
565		radeon_map_framebuffer(ctx, ctx->ReadBuffer);
566}
567
568static void radeonSpanRenderFinish(struct gl_context * ctx)
569{
570	int i;
571
572	_swrast_flush(ctx);
573
574	for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++)
575		if (ctx->Texture.Unit[i]._ReallyEnabled)
576			radeon_swrast_unmap_texture_images(ctx, ctx->Texture.Unit[i]._Current);
577
578	radeon_unmap_framebuffer(ctx, ctx->DrawBuffer);
579	if (ctx->ReadBuffer != ctx->DrawBuffer)
580		radeon_unmap_framebuffer(ctx, ctx->ReadBuffer);
581}
582
583void radeonInitSpanFuncs(struct gl_context * ctx)
584{
585	struct swrast_device_driver *swdd =
586	    _swrast_GetDeviceDriverReference(ctx);
587	swdd->SpanRenderStart = radeonSpanRenderStart;
588	swdd->SpanRenderFinish = radeonSpanRenderFinish;
589}
590
591/**
592 * Plug in the Get/Put routines for the given driRenderbuffer.
593 */
594static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb)
595{
596	if (rrb->base.Format == MESA_FORMAT_RGB565) {
597		radeonInitPointers_RGB565(&rrb->base);
598	} else if (rrb->base.Format == MESA_FORMAT_RGB565_REV) {
599		radeonInitPointers_RGB565_REV(&rrb->base);
600	} else if (rrb->base.Format == MESA_FORMAT_XRGB8888) {
601		radeonInitPointers_xRGB8888(&rrb->base);
602        } else if (rrb->base.Format == MESA_FORMAT_XRGB8888_REV) {
603		radeonInitPointers_BGRx8888(&rrb->base);
604	} else if (rrb->base.Format == MESA_FORMAT_ARGB8888) {
605		radeonInitPointers_ARGB8888(&rrb->base);
606        } else if (rrb->base.Format == MESA_FORMAT_ARGB8888_REV) {
607		radeonInitPointers_BGRA8888(&rrb->base);
608	} else if (rrb->base.Format == MESA_FORMAT_ARGB4444) {
609		radeonInitPointers_ARGB4444(&rrb->base);
610	} else if (rrb->base.Format == MESA_FORMAT_ARGB4444_REV) {
611		radeonInitPointers_ARGB4444_REV(&rrb->base);
612	} else if (rrb->base.Format == MESA_FORMAT_ARGB1555) {
613		radeonInitPointers_ARGB1555(&rrb->base);
614	} else if (rrb->base.Format == MESA_FORMAT_ARGB1555_REV) {
615		radeonInitPointers_ARGB1555_REV(&rrb->base);
616	} else if (rrb->base.Format == MESA_FORMAT_Z16) {
617		radeonInitDepthPointers_z16(&rrb->base);
618	} else if (rrb->base.Format == MESA_FORMAT_X8_Z24) {
619		radeonInitDepthPointers_z24(&rrb->base);
620	} else if (rrb->base.Format == MESA_FORMAT_S8_Z24) {
621		radeonInitDepthPointers_s8_z24(&rrb->base);
622	} else if (rrb->base.Format == MESA_FORMAT_S8) {
623		radeonInitStencilPointers_s8_z24(&rrb->base);
624	} else {
625		fprintf(stderr, "radeonSetSpanFunctions: bad format: 0x%04X\n", rrb->base.Format);
626	}
627}
628