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