1 /************************************************************************** 2 * 3 * Copyright 2008 Red Hat Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 29 #include "main/imports.h" 30 #include "main/macros.h" 31 #include "main/mtypes.h" 32 #include "main/enums.h" 33 #include "main/fbobject.h" 34 #include "main/framebuffer.h" 35 #include "main/renderbuffer.h" 36 #include "main/context.h" 37 #include "swrast/swrast.h" 38 #include "drivers/common/meta.h" 39 40 #include "radeon_common.h" 41 #include "radeon_mipmap_tree.h" 42 43 #define FILE_DEBUG_FLAG RADEON_TEXTURE 44 #define DBG(...) do { \ 45 if (RADEON_DEBUG & FILE_DEBUG_FLAG) \ 46 printf(__VA_ARGS__); \ 47 } while(0) 48 49 static void 50 radeon_delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb) 51 { 52 struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); 53 54 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 55 "%s(rb %p, rrb %p) \n", 56 __func__, rb, rrb); 57 58 assert(rrb); 59 60 if (rrb && rrb->bo) { 61 radeon_bo_unref(rrb->bo); 62 } 63 _mesa_delete_renderbuffer(ctx, rb); 64 } 65 66 #if defined(RADEON_R100) 67 static GLuint get_depth_z32(const struct radeon_renderbuffer * rrb, 68 GLint x, GLint y) 69 { 70 GLuint ba, address = 0; 71 72 ba = (y >> 4) * (rrb->pitch >> 6) + (x >> 4); 73 74 address |= (x & 0x7) << 2; 75 address |= (y & 0x3) << 5; 76 address |= (((x & 0x10) >> 2) ^ (y & 0x4)) << 5; 77 address |= (ba & 3) << 8; 78 address |= (y & 0x8) << 7; 79 address |= (((x & 0x8) << 1) ^ (y & 0x10)) << 7; 80 address |= (ba & ~0x3) << 10; 81 return address; 82 } 83 84 static GLuint get_depth_z16(const struct radeon_renderbuffer * rrb, 85 GLint x, GLint y) 86 { 87 GLuint ba, address = 0; /* a[0] = 0 */ 88 89 ba = (y / 16) * (rrb->pitch >> 6) + (x / 32); 90 91 address |= (x & 0x7) << 1; /* a[1..3] = x[0..2] */ 92 address |= (y & 0x7) << 4; /* a[4..6] = y[0..2] */ 93 address |= (x & 0x8) << 4; /* a[7] = x[3] */ 94 address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ 95 address |= (y & 0x8) << 7; /* a[10] = y[3] */ 96 address |= ((x & 0x10) ^ (y & 0x10)) << 7;/* a[11] = x[4] ^ y[4] */ 97 address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ 98 return address; 99 } 100 #endif 101 102 #if defined(RADEON_R200) 103 static GLuint get_depth_z32(const struct radeon_renderbuffer * rrb, 104 GLint x, GLint y) 105 { 106 GLuint offset; 107 GLuint b; 108 offset = 0; 109 b = (((y & 0x7ff) >> 4) * (rrb->pitch >> 7) + (x >> 5)); 110 offset += (b >> 1) << 12; 111 offset += (((rrb->pitch >> 7) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11; 112 offset += ((y >> 2) & 0x3) << 9; 113 offset += ((x >> 2) & 0x1) << 8; 114 offset += ((x >> 3) & 0x3) << 6; 115 offset += ((y >> 1) & 0x1) << 5; 116 offset += ((x >> 1) & 0x1) << 4; 117 offset += (y & 0x1) << 3; 118 offset += (x & 0x1) << 2; 119 120 return offset; 121 } 122 123 static GLuint get_depth_z16(const struct radeon_renderbuffer *rrb, 124 GLint x, GLint y) 125 { 126 GLuint offset; 127 GLuint b; 128 129 offset = 0; 130 b = (((y >> 4) * (rrb->pitch >> 7) + (x >> 6))); 131 offset += (b >> 1) << 12; 132 offset += (((rrb->pitch >> 7) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11; 133 offset += ((y >> 2) & 0x3) << 9; 134 offset += ((x >> 3) & 0x1) << 8; 135 offset += ((x >> 4) & 0x3) << 6; 136 offset += ((x >> 2) & 0x1) << 5; 137 offset += ((y >> 1) & 0x1) << 4; 138 offset += ((x >> 1) & 0x1) << 3; 139 offset += (y & 0x1) << 2; 140 offset += (x & 0x1) << 1; 141 142 return offset; 143 } 144 #endif 145 146 static void 147 radeon_map_renderbuffer_s8z24(struct gl_renderbuffer *rb, 148 GLuint x, GLuint y, GLuint w, GLuint h, 149 GLbitfield mode, 150 GLubyte **out_map, 151 GLint *out_stride) 152 { 153 struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); 154 uint32_t *untiled_s8z24_map, *tiled_s8z24_map; 155 int ret; 156 int y_flip = (rb->Name == 0) ? -1 : 1; 157 int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0; 158 uint32_t pitch = w * rrb->cpp; 159 160 rrb->map_pitch = pitch; 161 162 rrb->map_buffer = malloc(w * h * 4); 163 ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT)); 164 assert(!ret); 165 (void) ret; 166 untiled_s8z24_map = rrb->map_buffer; 167 tiled_s8z24_map = rrb->bo->ptr; 168 169 for (uint32_t pix_y = 0; pix_y < h; ++ pix_y) { 170 for (uint32_t pix_x = 0; pix_x < w; ++pix_x) { 171 uint32_t flipped_y = y_flip * (int32_t)(y + pix_y) + y_bias; 172 uint32_t src_offset = get_depth_z32(rrb, x + pix_x, flipped_y); 173 uint32_t dst_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp; 174 untiled_s8z24_map[dst_offset/4] = tiled_s8z24_map[src_offset/4]; 175 } 176 } 177 178 radeon_bo_unmap(rrb->bo); 179 180 *out_map = rrb->map_buffer; 181 *out_stride = rrb->map_pitch; 182 } 183 184 static void 185 radeon_map_renderbuffer_z16(struct gl_renderbuffer *rb, 186 GLuint x, GLuint y, GLuint w, GLuint h, 187 GLbitfield mode, 188 GLubyte **out_map, 189 GLint *out_stride) 190 { 191 struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); 192 uint16_t *untiled_z16_map, *tiled_z16_map; 193 int ret; 194 int y_flip = (rb->Name == 0) ? -1 : 1; 195 int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0; 196 uint32_t pitch = w * rrb->cpp; 197 198 rrb->map_pitch = pitch; 199 200 rrb->map_buffer = malloc(w * h * 2); 201 ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT)); 202 assert(!ret); 203 (void) ret; 204 205 untiled_z16_map = rrb->map_buffer; 206 tiled_z16_map = rrb->bo->ptr; 207 208 for (uint32_t pix_y = 0; pix_y < h; ++ pix_y) { 209 for (uint32_t pix_x = 0; pix_x < w; ++pix_x) { 210 uint32_t flipped_y = y_flip * (int32_t)(y + pix_y) + y_bias; 211 uint32_t src_offset = get_depth_z16(rrb, x + pix_x, flipped_y); 212 uint32_t dst_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp; 213 untiled_z16_map[dst_offset/2] = tiled_z16_map[src_offset/2]; 214 } 215 } 216 217 radeon_bo_unmap(rrb->bo); 218 219 *out_map = rrb->map_buffer; 220 *out_stride = rrb->map_pitch; 221 } 222 223 static void 224 radeon_map_renderbuffer(struct gl_context *ctx, 225 struct gl_renderbuffer *rb, 226 GLuint x, GLuint y, GLuint w, GLuint h, 227 GLbitfield mode, 228 GLubyte **out_map, 229 GLint *out_stride) 230 { 231 struct radeon_context *const rmesa = RADEON_CONTEXT(ctx); 232 struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); 233 GLubyte *map; 234 GLboolean ok; 235 int stride, flip_stride; 236 int ret; 237 int src_x, src_y; 238 239 if (!rrb || !rrb->bo) { 240 *out_map = NULL; 241 *out_stride = 0; 242 return; 243 } 244 245 rrb->map_mode = mode; 246 rrb->map_x = x; 247 rrb->map_y = y; 248 rrb->map_w = w; 249 rrb->map_h = h; 250 rrb->map_pitch = rrb->pitch; 251 252 ok = rmesa->vtbl.check_blit(rb->Format, rrb->pitch / rrb->cpp); 253 if (ok) { 254 if (rb->Name) { 255 src_x = x; 256 src_y = y; 257 } else { 258 src_x = x; 259 src_y = rrb->base.Base.Height - y - h; 260 } 261 262 /* Make a temporary buffer and blit the current contents of the renderbuffer 263 * out to it. This gives us linear access to the buffer, instead of having 264 * to do detiling in software. 265 */ 266 267 rrb->map_pitch = rrb->pitch; 268 269 assert(!rrb->map_bo); 270 rrb->map_bo = radeon_bo_open(rmesa->radeonScreen->bom, 0, 271 rrb->map_pitch * h, 4, 272 RADEON_GEM_DOMAIN_GTT, 0); 273 274 ok = rmesa->vtbl.blit(ctx, rrb->bo, rrb->draw_offset, 275 rb->Format, rrb->pitch / rrb->cpp, 276 rb->Width, rb->Height, 277 src_x, src_y, 278 rrb->map_bo, 0, 279 rb->Format, rrb->map_pitch / rrb->cpp, 280 w, h, 281 0, 0, 282 w, h, 283 GL_FALSE); 284 assert(ok); 285 286 ret = radeon_bo_map(rrb->map_bo, !!(mode & GL_MAP_WRITE_BIT)); 287 assert(!ret); 288 289 map = rrb->map_bo->ptr; 290 291 if (rb->Name) { 292 *out_map = map; 293 *out_stride = rrb->map_pitch; 294 } else { 295 *out_map = map + (h - 1) * rrb->map_pitch; 296 *out_stride = -rrb->map_pitch; 297 } 298 return; 299 } 300 301 /* sw fallback flush stuff */ 302 if (radeon_bo_is_referenced_by_cs(rrb->bo, rmesa->cmdbuf.cs)) { 303 radeon_firevertices(rmesa); 304 } 305 306 if ((rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_DEPTH_ALWAYS_TILED) && !rrb->has_surface) { 307 if (rb->Format == MESA_FORMAT_Z24_UNORM_S8_UINT || rb->Format == MESA_FORMAT_Z24_UNORM_X8_UINT) { 308 radeon_map_renderbuffer_s8z24(rb, x, y, w, h, 309 mode, out_map, out_stride); 310 return; 311 } 312 if (rb->Format == MESA_FORMAT_Z_UNORM16) { 313 radeon_map_renderbuffer_z16(rb, x, y, w, h, 314 mode, out_map, out_stride); 315 return; 316 } 317 } 318 319 ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT)); 320 assert(!ret); 321 (void) ret; 322 323 map = rrb->bo->ptr; 324 stride = rrb->map_pitch; 325 326 if (rb->Name == 0) { 327 y = rb->Height - 1 - y; 328 flip_stride = -stride; 329 } else { 330 flip_stride = stride; 331 map += rrb->draw_offset; 332 } 333 334 map += x * rrb->cpp; 335 map += (int)y * stride; 336 337 *out_map = map; 338 *out_stride = flip_stride; 339 } 340 341 static void 342 radeon_unmap_renderbuffer_s8z24(struct gl_context *ctx, 343 struct gl_renderbuffer *rb) 344 { 345 struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); 346 347 if (!rrb->map_buffer) 348 return; 349 350 if (rrb->map_mode & GL_MAP_WRITE_BIT) { 351 uint32_t *untiled_s8z24_map = rrb->map_buffer; 352 uint32_t *tiled_s8z24_map; 353 int y_flip = (rb->Name == 0) ? -1 : 1; 354 int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0; 355 356 radeon_bo_map(rrb->bo, 1); 357 358 tiled_s8z24_map = rrb->bo->ptr; 359 360 for (uint32_t pix_y = 0; pix_y < rrb->map_h; pix_y++) { 361 for (uint32_t pix_x = 0; pix_x < rrb->map_w; pix_x++) { 362 uint32_t flipped_y = y_flip * (int32_t)(pix_y + rrb->map_y) + y_bias; 363 uint32_t dst_offset = get_depth_z32(rrb, rrb->map_x + pix_x, flipped_y); 364 uint32_t src_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp; 365 tiled_s8z24_map[dst_offset/4] = untiled_s8z24_map[src_offset/4]; 366 } 367 } 368 radeon_bo_unmap(rrb->bo); 369 } 370 free(rrb->map_buffer); 371 rrb->map_buffer = NULL; 372 } 373 374 static void 375 radeon_unmap_renderbuffer_z16(struct gl_context *ctx, 376 struct gl_renderbuffer *rb) 377 { 378 struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); 379 380 if (!rrb->map_buffer) 381 return; 382 383 if (rrb->map_mode & GL_MAP_WRITE_BIT) { 384 uint16_t *untiled_z16_map = rrb->map_buffer; 385 uint16_t *tiled_z16_map; 386 int y_flip = (rb->Name == 0) ? -1 : 1; 387 int y_bias = (rb->Name == 0) ? (rb->Height - 1) : 0; 388 389 radeon_bo_map(rrb->bo, 1); 390 391 tiled_z16_map = rrb->bo->ptr; 392 393 for (uint32_t pix_y = 0; pix_y < rrb->map_h; pix_y++) { 394 for (uint32_t pix_x = 0; pix_x < rrb->map_w; pix_x++) { 395 uint32_t flipped_y = y_flip * (int32_t)(pix_y + rrb->map_y) + y_bias; 396 uint32_t dst_offset = get_depth_z16(rrb, rrb->map_x + pix_x, flipped_y); 397 uint32_t src_offset = pix_y * rrb->map_pitch + pix_x * rrb->cpp; 398 tiled_z16_map[dst_offset/2] = untiled_z16_map[src_offset/2]; 399 } 400 } 401 radeon_bo_unmap(rrb->bo); 402 } 403 free(rrb->map_buffer); 404 rrb->map_buffer = NULL; 405 } 406 407 408 static void 409 radeon_unmap_renderbuffer(struct gl_context *ctx, 410 struct gl_renderbuffer *rb) 411 { 412 struct radeon_context *const rmesa = RADEON_CONTEXT(ctx); 413 struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); 414 415 if ((rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_DEPTH_ALWAYS_TILED) && !rrb->has_surface) { 416 if (rb->Format == MESA_FORMAT_Z24_UNORM_S8_UINT || rb->Format == MESA_FORMAT_Z24_UNORM_X8_UINT) { 417 radeon_unmap_renderbuffer_s8z24(ctx, rb); 418 return; 419 } 420 if (rb->Format == MESA_FORMAT_Z_UNORM16) { 421 radeon_unmap_renderbuffer_z16(ctx, rb); 422 return; 423 } 424 } 425 426 if (!rrb->map_bo) { 427 if (rrb->bo) 428 radeon_bo_unmap(rrb->bo); 429 return; 430 } 431 432 radeon_bo_unmap(rrb->map_bo); 433 434 if (rrb->map_mode & GL_MAP_WRITE_BIT) { 435 GLboolean ok; 436 ok = rmesa->vtbl.blit(ctx, rrb->map_bo, 0, 437 rb->Format, rrb->map_pitch / rrb->cpp, 438 rrb->map_w, rrb->map_h, 439 0, 0, 440 rrb->bo, rrb->draw_offset, 441 rb->Format, rrb->pitch / rrb->cpp, 442 rb->Width, rb->Height, 443 rrb->map_x, rrb->map_y, 444 rrb->map_w, rrb->map_h, 445 GL_FALSE); 446 assert(ok); 447 (void) ok; 448 } 449 450 radeon_bo_unref(rrb->map_bo); 451 rrb->map_bo = NULL; 452 } 453 454 455 /** 456 * Called via glRenderbufferStorageEXT() to set the format and allocate 457 * storage for a user-created renderbuffer. 458 */ 459 static GLboolean 460 radeon_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, 461 GLenum internalFormat, 462 GLuint width, GLuint height) 463 { 464 struct radeon_context *radeon = RADEON_CONTEXT(ctx); 465 struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); 466 uint32_t size, pitch; 467 int cpp; 468 469 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 470 "%s(%p, rb %p) \n", 471 __func__, ctx, rb); 472 473 assert(rb->Name != 0); 474 switch (internalFormat) { 475 case GL_R3_G3_B2: 476 case GL_RGB4: 477 case GL_RGB5: 478 rb->Format = _radeon_texformat_rgb565; 479 cpp = 2; 480 break; 481 case GL_RGB: 482 case GL_RGB8: 483 case GL_RGB10: 484 case GL_RGB12: 485 case GL_RGB16: 486 rb->Format = _radeon_texformat_argb8888; 487 cpp = 4; 488 break; 489 case GL_RGBA: 490 case GL_RGBA2: 491 case GL_RGBA4: 492 case GL_RGB5_A1: 493 case GL_RGBA8: 494 case GL_RGB10_A2: 495 case GL_RGBA12: 496 case GL_RGBA16: 497 rb->Format = _radeon_texformat_argb8888; 498 cpp = 4; 499 break; 500 case GL_STENCIL_INDEX: 501 case GL_STENCIL_INDEX1_EXT: 502 case GL_STENCIL_INDEX4_EXT: 503 case GL_STENCIL_INDEX8_EXT: 504 case GL_STENCIL_INDEX16_EXT: 505 /* alloc a depth+stencil buffer */ 506 rb->Format = MESA_FORMAT_Z24_UNORM_S8_UINT; 507 cpp = 4; 508 break; 509 case GL_DEPTH_COMPONENT16: 510 rb->Format = MESA_FORMAT_Z_UNORM16; 511 cpp = 2; 512 break; 513 case GL_DEPTH_COMPONENT: 514 case GL_DEPTH_COMPONENT24: 515 case GL_DEPTH_COMPONENT32: 516 rb->Format = MESA_FORMAT_Z24_UNORM_X8_UINT; 517 cpp = 4; 518 break; 519 case GL_DEPTH_STENCIL_EXT: 520 case GL_DEPTH24_STENCIL8_EXT: 521 rb->Format = MESA_FORMAT_Z24_UNORM_S8_UINT; 522 cpp = 4; 523 break; 524 default: 525 _mesa_problem(ctx, 526 "Unexpected format in radeon_alloc_renderbuffer_storage"); 527 return GL_FALSE; 528 } 529 530 rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat); 531 532 if (ctx->Driver.Flush) 533 ctx->Driver.Flush(ctx); /* +r6/r7 */ 534 535 if (rrb->bo) 536 radeon_bo_unref(rrb->bo); 537 538 pitch = ((cpp * width + 63) & ~63) / cpp; 539 540 if (RADEON_DEBUG & RADEON_MEMORY) 541 fprintf(stderr,"Allocating %d x %d radeon RBO (pitch %d)\n", width, 542 height, pitch); 543 544 size = pitch * height * cpp; 545 rrb->pitch = pitch * cpp; 546 rrb->cpp = cpp; 547 rrb->bo = radeon_bo_open(radeon->radeonScreen->bom, 548 0, 549 size, 550 0, 551 RADEON_GEM_DOMAIN_VRAM, 552 0); 553 rb->Width = width; 554 rb->Height = height; 555 return GL_TRUE; 556 } 557 558 static void 559 radeon_image_target_renderbuffer_storage(struct gl_context *ctx, 560 struct gl_renderbuffer *rb, 561 void *image_handle) 562 { 563 radeonContextPtr radeon = RADEON_CONTEXT(ctx); 564 struct radeon_renderbuffer *rrb; 565 __DRIscreen *screen; 566 __DRIimage *image; 567 568 screen = radeon->radeonScreen->driScreen; 569 image = screen->dri2.image->lookupEGLImage(screen, image_handle, 570 screen->loaderPrivate); 571 if (image == NULL) 572 return; 573 574 rrb = radeon_renderbuffer(rb); 575 576 if (ctx->Driver.Flush) 577 ctx->Driver.Flush(ctx); /* +r6/r7 */ 578 579 if (rrb->bo) 580 radeon_bo_unref(rrb->bo); 581 rrb->bo = image->bo; 582 radeon_bo_ref(rrb->bo); 583 fprintf(stderr, "image->bo: %p, name: %d, rbs: w %d -> p %d\n", image->bo, image->bo->handle, 584 image->width, image->pitch); 585 586 rrb->cpp = image->cpp; 587 rrb->pitch = image->pitch * image->cpp; 588 589 rb->Format = image->format; 590 rb->InternalFormat = image->internal_format; 591 rb->Width = image->width; 592 rb->Height = image->height; 593 rb->Format = image->format; 594 rb->_BaseFormat = _mesa_base_fbo_format(&radeon->glCtx, 595 image->internal_format); 596 rb->NeedsFinishRenderTexture = GL_TRUE; 597 } 598 599 /** 600 * Called for each hardware renderbuffer when a _window_ is resized. 601 * Just update fields. 602 * Not used for user-created renderbuffers! 603 */ 604 static GLboolean 605 radeon_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, 606 GLenum internalFormat, GLuint width, GLuint height) 607 { 608 assert(rb->Name == 0); 609 rb->Width = width; 610 rb->Height = height; 611 rb->InternalFormat = internalFormat; 612 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 613 "%s(%p, rb %p) \n", 614 __func__, ctx, rb); 615 616 617 return GL_TRUE; 618 } 619 620 /** Dummy function for gl_renderbuffer::AllocStorage() */ 621 static GLboolean 622 radeon_nop_alloc_storage(struct gl_context * ctx, 623 UNUSED struct gl_renderbuffer *rb, 624 UNUSED GLenum internalFormat, 625 UNUSED GLuint width, 626 UNUSED GLuint height) 627 { 628 _mesa_problem(ctx, "radeon_op_alloc_storage should never be called."); 629 return GL_FALSE; 630 } 631 632 633 /** 634 * Create a renderbuffer for a window's color, depth and/or stencil buffer. 635 * Not used for user-created renderbuffers. 636 */ 637 struct radeon_renderbuffer * 638 radeon_create_renderbuffer(mesa_format format, __DRIdrawable *driDrawPriv) 639 { 640 struct radeon_renderbuffer *rrb; 641 struct gl_renderbuffer *rb; 642 643 rrb = CALLOC_STRUCT(radeon_renderbuffer); 644 645 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 646 "%s( rrb %p ) \n", 647 __func__, rrb); 648 649 if (!rrb) 650 return NULL; 651 652 rb = &rrb->base.Base; 653 654 _mesa_init_renderbuffer(rb, 0); 655 rb->ClassID = RADEON_RB_CLASS; 656 rb->Format = format; 657 rb->_BaseFormat = _mesa_get_format_base_format(format); 658 rb->InternalFormat = _mesa_get_format_base_format(format); 659 660 rrb->dPriv = driDrawPriv; 661 662 rb->Delete = radeon_delete_renderbuffer; 663 rb->AllocStorage = radeon_alloc_window_storage; 664 665 rrb->bo = NULL; 666 return rrb; 667 } 668 669 static struct gl_renderbuffer * 670 radeon_new_renderbuffer(struct gl_context * ctx, GLuint name) 671 { 672 struct radeon_renderbuffer *rrb; 673 struct gl_renderbuffer *rb; 674 675 676 rrb = CALLOC_STRUCT(radeon_renderbuffer); 677 678 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 679 "%s(%p, rrb %p) \n", 680 __func__, ctx, rrb); 681 682 if (!rrb) 683 return NULL; 684 685 rb = &rrb->base.Base; 686 687 _mesa_init_renderbuffer(rb, name); 688 rb->ClassID = RADEON_RB_CLASS; 689 rb->Delete = radeon_delete_renderbuffer; 690 rb->AllocStorage = radeon_alloc_renderbuffer_storage; 691 692 return rb; 693 } 694 695 static void 696 radeon_bind_framebuffer(struct gl_context * ctx, GLenum target, 697 struct gl_framebuffer *fb, struct gl_framebuffer *fbread) 698 { 699 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 700 "%s(%p, fb %p, target %s) \n", 701 __func__, ctx, fb, 702 _mesa_enum_to_string(target)); 703 704 if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { 705 radeon_draw_buffer(ctx, fb); 706 } 707 else { 708 /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */ 709 } 710 } 711 712 static void 713 radeon_framebuffer_renderbuffer(struct gl_context * ctx, 714 struct gl_framebuffer *fb, 715 GLenum attachment, struct gl_renderbuffer *rb) 716 { 717 718 if (ctx->Driver.Flush) 719 ctx->Driver.Flush(ctx); /* +r6/r7 */ 720 721 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 722 "%s(%p, fb %p, rb %p) \n", 723 __func__, ctx, fb, rb); 724 725 _mesa_FramebufferRenderbuffer_sw(ctx, fb, attachment, rb); 726 radeon_draw_buffer(ctx, fb); 727 } 728 729 static GLboolean 730 radeon_update_wrapper(struct gl_context *ctx, struct radeon_renderbuffer *rrb, 731 struct gl_texture_image *texImage) 732 { 733 struct gl_renderbuffer *rb = &rrb->base.Base; 734 735 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 736 "%s(%p, rrb %p, texImage %p, texFormat %s) \n", 737 __func__, ctx, rrb, texImage, _mesa_get_format_name(texImage->TexFormat)); 738 739 rrb->cpp = _mesa_get_format_bytes(texImage->TexFormat); 740 rrb->pitch = texImage->Width * rrb->cpp; 741 rb->Format = texImage->TexFormat; 742 rb->InternalFormat = texImage->InternalFormat; 743 rb->_BaseFormat = _mesa_get_format_base_format(rb->Format); 744 rb->Width = texImage->Width; 745 rb->Height = texImage->Height; 746 rb->Delete = radeon_delete_renderbuffer; 747 rb->AllocStorage = radeon_nop_alloc_storage; 748 749 return GL_TRUE; 750 } 751 752 static void 753 radeon_render_texture(struct gl_context * ctx, 754 struct gl_framebuffer *fb, 755 struct gl_renderbuffer_attachment *att) 756 { 757 struct gl_renderbuffer *rb = att->Renderbuffer; 758 struct gl_texture_image *newImage = rb->TexImage; 759 struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); 760 radeon_texture_image *radeon_image; 761 GLuint imageOffset; 762 763 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 764 "%s(%p, fb %p, rrb %p, att %p)\n", 765 __func__, ctx, fb, rrb, att); 766 767 (void) fb; 768 769 assert(newImage); 770 771 radeon_image = (radeon_texture_image *)newImage; 772 773 if (!radeon_image->mt) { 774 /* Fallback on drawing to a texture without a miptree. 775 */ 776 _swrast_render_texture(ctx, fb, att); 777 return; 778 } 779 780 if (!radeon_update_wrapper(ctx, rrb, newImage)) { 781 _swrast_render_texture(ctx, fb, att); 782 return; 783 } 784 785 DBG("Begin render texture tex=%u w=%d h=%d refcount=%d\n", 786 att->Texture->Name, newImage->Width, newImage->Height, 787 rb->RefCount); 788 789 /* point the renderbufer's region to the texture image region */ 790 if (rrb->bo != radeon_image->mt->bo) { 791 if (rrb->bo) 792 radeon_bo_unref(rrb->bo); 793 rrb->bo = radeon_image->mt->bo; 794 radeon_bo_ref(rrb->bo); 795 } 796 797 /* compute offset of the particular 2D image within the texture region */ 798 imageOffset = radeon_miptree_image_offset(radeon_image->mt, 799 att->CubeMapFace, 800 att->TextureLevel); 801 802 if (att->Texture->Target == GL_TEXTURE_3D) { 803 imageOffset += radeon_image->mt->levels[att->TextureLevel].rowstride * 804 radeon_image->mt->levels[att->TextureLevel].height * 805 att->Zoffset; 806 } 807 808 /* store that offset in the region, along with the correct pitch for 809 * the image we are rendering to */ 810 rrb->draw_offset = imageOffset; 811 rrb->pitch = radeon_image->mt->levels[att->TextureLevel].rowstride; 812 radeon_image->used_as_render_target = GL_TRUE; 813 814 /* update drawing region, etc */ 815 radeon_draw_buffer(ctx, fb); 816 } 817 818 static void 819 radeon_finish_render_texture(struct gl_context *ctx, struct gl_renderbuffer *rb) 820 { 821 struct gl_texture_image *image = rb->TexImage; 822 radeon_texture_image *radeon_image = (radeon_texture_image *)image; 823 824 if (radeon_image) 825 radeon_image->used_as_render_target = GL_FALSE; 826 827 if (ctx->Driver.Flush) 828 ctx->Driver.Flush(ctx); /* +r6/r7 */ 829 } 830 static void 831 radeon_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) 832 { 833 radeonContextPtr radeon = RADEON_CONTEXT(ctx); 834 mesa_format mesa_format; 835 int i; 836 837 for (i = -2; i < (GLint) ctx->Const.MaxColorAttachments; i++) { 838 struct gl_renderbuffer_attachment *att; 839 if (i == -2) { 840 att = &fb->Attachment[BUFFER_DEPTH]; 841 } else if (i == -1) { 842 att = &fb->Attachment[BUFFER_STENCIL]; 843 } else { 844 att = &fb->Attachment[BUFFER_COLOR0 + i]; 845 } 846 847 if (att->Type == GL_TEXTURE) { 848 mesa_format = att->Renderbuffer->TexImage->TexFormat; 849 } else { 850 /* All renderbuffer formats are renderable, but not sampable */ 851 continue; 852 } 853 854 if (!radeon->vtbl.is_format_renderable(mesa_format)){ 855 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED; 856 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 857 "%s: HW doesn't support format %s as output format of attachment %d\n", 858 __func__, _mesa_get_format_name(mesa_format), i); 859 return; 860 } 861 } 862 } 863 864 void radeon_fbo_init(struct radeon_context *radeon) 865 { 866 radeon->glCtx.Driver.NewRenderbuffer = radeon_new_renderbuffer; 867 radeon->glCtx.Driver.MapRenderbuffer = radeon_map_renderbuffer; 868 radeon->glCtx.Driver.UnmapRenderbuffer = radeon_unmap_renderbuffer; 869 radeon->glCtx.Driver.BindFramebuffer = radeon_bind_framebuffer; 870 radeon->glCtx.Driver.FramebufferRenderbuffer = radeon_framebuffer_renderbuffer; 871 radeon->glCtx.Driver.RenderTexture = radeon_render_texture; 872 radeon->glCtx.Driver.FinishRenderTexture = radeon_finish_render_texture; 873 radeon->glCtx.Driver.ValidateFramebuffer = radeon_validate_framebuffer; 874 radeon->glCtx.Driver.BlitFramebuffer = _mesa_meta_and_swrast_BlitFramebuffer; 875 radeon->glCtx.Driver.EGLImageTargetRenderbufferStorage = 876 radeon_image_target_renderbuffer_storage; 877 } 878 879 880 void radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb, 881 struct radeon_bo *bo) 882 { 883 struct radeon_bo *old; 884 old = rb->bo; 885 rb->bo = bo; 886 radeon_bo_ref(bo); 887 if (old) 888 radeon_bo_unref(old); 889 } 890