radeon_span.c revision f9995b30756140724f41daf963fa06167912be7f
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; 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; 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; 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; 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