1/* 2 * Copyright 2009 Marek Olšák <maraeo@gmail.com> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 22 23#include "r300_context.h" 24#include "r300_emit.h" 25#include "r300_texture.h" 26#include "r300_reg.h" 27 28#include "util/format/u_format.h" 29#include "util/half_float.h" 30#include "util/u_pack_color.h" 31#include "util/u_surface.h" 32 33enum r300_blitter_op /* bitmask */ 34{ 35 R300_STOP_QUERY = 1, 36 R300_SAVE_TEXTURES = 2, 37 R300_SAVE_FRAMEBUFFER = 4, 38 R300_IGNORE_RENDER_COND = 8, 39 40 R300_CLEAR = R300_STOP_QUERY, 41 42 R300_CLEAR_SURFACE = R300_STOP_QUERY | R300_SAVE_FRAMEBUFFER, 43 44 R300_COPY = R300_STOP_QUERY | R300_SAVE_FRAMEBUFFER | 45 R300_SAVE_TEXTURES | R300_IGNORE_RENDER_COND, 46 47 R300_BLIT = R300_STOP_QUERY | R300_SAVE_FRAMEBUFFER | 48 R300_SAVE_TEXTURES, 49 50 R300_DECOMPRESS = R300_STOP_QUERY | R300_IGNORE_RENDER_COND, 51}; 52 53static void r300_blitter_begin(struct r300_context* r300, enum r300_blitter_op op) 54{ 55 if ((op & R300_STOP_QUERY) && r300->query_current) { 56 r300->blitter_saved_query = r300->query_current; 57 r300_stop_query(r300); 58 } 59 60 /* Yeah we have to save all those states to ensure the blitter operation 61 * is really transparent. The states will be restored by the blitter once 62 * copying is done. */ 63 util_blitter_save_blend(r300->blitter, r300->blend_state.state); 64 util_blitter_save_depth_stencil_alpha(r300->blitter, r300->dsa_state.state); 65 util_blitter_save_stencil_ref(r300->blitter, &(r300->stencil_ref)); 66 util_blitter_save_rasterizer(r300->blitter, r300->rs_state.state); 67 util_blitter_save_fragment_shader(r300->blitter, r300->fs.state); 68 util_blitter_save_vertex_shader(r300->blitter, r300->vs_state.state); 69 util_blitter_save_viewport(r300->blitter, &r300->viewport); 70 util_blitter_save_scissor(r300->blitter, r300->scissor_state.state); 71 util_blitter_save_sample_mask(r300->blitter, *(unsigned*)r300->sample_mask.state); 72 util_blitter_save_vertex_buffer_slot(r300->blitter, r300->vertex_buffer); 73 util_blitter_save_vertex_elements(r300->blitter, r300->velems); 74 75 if (op & R300_SAVE_FRAMEBUFFER) { 76 util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state); 77 } 78 79 if (op & R300_SAVE_TEXTURES) { 80 struct r300_textures_state* state = 81 (struct r300_textures_state*)r300->textures_state.state; 82 83 util_blitter_save_fragment_sampler_states( 84 r300->blitter, state->sampler_state_count, 85 (void**)state->sampler_states); 86 87 util_blitter_save_fragment_sampler_views( 88 r300->blitter, state->sampler_view_count, 89 (struct pipe_sampler_view**)state->sampler_views); 90 } 91 92 if (op & R300_IGNORE_RENDER_COND) { 93 /* Save the flag. */ 94 r300->blitter_saved_skip_rendering = r300->skip_rendering+1; 95 r300->skip_rendering = FALSE; 96 } else { 97 r300->blitter_saved_skip_rendering = 0; 98 } 99} 100 101static void r300_blitter_end(struct r300_context *r300) 102{ 103 if (r300->blitter_saved_query) { 104 r300_resume_query(r300, r300->blitter_saved_query); 105 r300->blitter_saved_query = NULL; 106 } 107 108 if (r300->blitter_saved_skip_rendering) { 109 /* Restore the flag. */ 110 r300->skip_rendering = r300->blitter_saved_skip_rendering-1; 111 } 112} 113 114static uint32_t r300_depth_clear_cb_value(enum pipe_format format, 115 const float* rgba) 116{ 117 union util_color uc; 118 util_pack_color(rgba, format, &uc); 119 120 if (util_format_get_blocksizebits(format) == 32) 121 return uc.ui[0]; 122 else 123 return uc.us | (uc.us << 16); 124} 125 126static boolean r300_cbzb_clear_allowed(struct r300_context *r300, 127 unsigned clear_buffers) 128{ 129 struct pipe_framebuffer_state *fb = 130 (struct pipe_framebuffer_state*)r300->fb_state.state; 131 132 /* Only color clear allowed, and only one colorbuffer. */ 133 if ((clear_buffers & ~PIPE_CLEAR_COLOR) != 0 || fb->nr_cbufs != 1 || !fb->cbufs[0]) 134 return FALSE; 135 136 return r300_surface(fb->cbufs[0])->cbzb_allowed; 137} 138 139static boolean r300_fast_zclear_allowed(struct r300_context *r300, 140 unsigned clear_buffers) 141{ 142 struct pipe_framebuffer_state *fb = 143 (struct pipe_framebuffer_state*)r300->fb_state.state; 144 145 return r300_resource(fb->zsbuf->texture)->tex.zmask_dwords[fb->zsbuf->u.tex.level] != 0; 146} 147 148static boolean r300_hiz_clear_allowed(struct r300_context *r300) 149{ 150 struct pipe_framebuffer_state *fb = 151 (struct pipe_framebuffer_state*)r300->fb_state.state; 152 153 return r300_resource(fb->zsbuf->texture)->tex.hiz_dwords[fb->zsbuf->u.tex.level] != 0; 154} 155 156static uint32_t r300_depth_clear_value(enum pipe_format format, 157 double depth, unsigned stencil) 158{ 159 switch (format) { 160 case PIPE_FORMAT_Z16_UNORM: 161 case PIPE_FORMAT_X8Z24_UNORM: 162 return util_pack_z(format, depth); 163 164 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 165 return util_pack_z_stencil(format, depth, stencil); 166 167 default: 168 assert(0); 169 return 0; 170 } 171} 172 173static uint32_t r300_hiz_clear_value(double depth) 174{ 175 uint32_t r = (uint32_t)(CLAMP(depth, 0, 1) * 255.5); 176 assert(r <= 255); 177 return r | (r << 8) | (r << 16) | (r << 24); 178} 179 180static void r300_set_clear_color(struct r300_context *r300, 181 const union pipe_color_union *color) 182{ 183 struct pipe_framebuffer_state *fb = 184 (struct pipe_framebuffer_state*)r300->fb_state.state; 185 union util_color uc; 186 187 memset(&uc, 0, sizeof(uc)); 188 util_pack_color(color->f, fb->cbufs[0]->format, &uc); 189 190 if (fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT || 191 fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16X16_FLOAT) { 192 /* (0,1,2,3) maps to (B,G,R,A) */ 193 r300->color_clear_value_gb = uc.h[0] | ((uint32_t)uc.h[1] << 16); 194 r300->color_clear_value_ar = uc.h[2] | ((uint32_t)uc.h[3] << 16); 195 } else { 196 r300->color_clear_value = uc.ui[0]; 197 } 198} 199 200DEBUG_GET_ONCE_BOOL_OPTION(hyperz, "RADEON_HYPERZ", FALSE) 201 202/* Clear currently bound buffers. */ 203static void r300_clear(struct pipe_context* pipe, 204 unsigned buffers, 205 const struct pipe_scissor_state *scissor_state, 206 const union pipe_color_union *color, 207 double depth, 208 unsigned stencil) 209{ 210 /* My notes about Zbuffer compression: 211 * 212 * 1) The zbuffer must be micro-tiled and whole microtiles must be 213 * written if compression is enabled. If microtiling is disabled, 214 * it locks up. 215 * 216 * 2) There is ZMASK RAM which contains a compressed zbuffer. 217 * Each dword of the Z Mask contains compression information 218 * for 16 4x4 pixel tiles, that is 2 bits for each tile. 219 * On chips with 2 Z pipes, every other dword maps to a different 220 * pipe. On newer chipsets, there is a new compression mode 221 * with 8x8 pixel tiles per 2 bits. 222 * 223 * 3) The FASTFILL bit has nothing to do with filling. It only tells hw 224 * it should look in the ZMASK RAM first before fetching from a real 225 * zbuffer. 226 * 227 * 4) If a pixel is in a cleared state, ZB_DEPTHCLEARVALUE is returned 228 * during zbuffer reads instead of the value that is actually stored 229 * in the zbuffer memory. A pixel is in a cleared state when its ZMASK 230 * is equal to 0. Therefore, if you clear ZMASK with zeros, you may 231 * leave the zbuffer memory uninitialized, but then you must enable 232 * compression, so that the ZMASK RAM is actually used. 233 * 234 * 5) Each 4x4 (or 8x8) tile is automatically decompressed and recompressed 235 * during zbuffer updates. A special decompressing operation should be 236 * used to fully decompress a zbuffer, which basically just stores all 237 * compressed tiles in ZMASK to the zbuffer memory. 238 * 239 * 6) For a 16-bit zbuffer, compression causes a hung with one or 240 * two samples and should not be used. 241 * 242 * 7) FORCE_COMPRESSED_STENCIL_VALUE should be enabled for stencil clears 243 * to avoid needless decompression. 244 * 245 * 8) Fastfill must not be used if reading of compressed Z data is disabled 246 * and writing of compressed Z data is enabled (RD/WR_COMP_ENABLE), 247 * i.e. it cannot be used to compress the zbuffer. 248 * 249 * 9) ZB_CB_CLEAR does not interact with zbuffer compression in any way. 250 * 251 * - Marek 252 */ 253 254 struct r300_context* r300 = r300_context(pipe); 255 struct pipe_framebuffer_state *fb = 256 (struct pipe_framebuffer_state*)r300->fb_state.state; 257 struct r300_hyperz_state *hyperz = 258 (struct r300_hyperz_state*)r300->hyperz_state.state; 259 uint32_t width = fb->width; 260 uint32_t height = fb->height; 261 uint32_t hyperz_dcv = hyperz->zb_depthclearvalue; 262 263 /* Use fast Z clear. 264 * The zbuffer must be in micro-tiled mode, otherwise it locks up. */ 265 if (buffers & PIPE_CLEAR_DEPTHSTENCIL) { 266 boolean zmask_clear, hiz_clear; 267 268 /* If both depth and stencil are present, they must be cleared together. */ 269 if (fb->zsbuf->texture->format == PIPE_FORMAT_S8_UINT_Z24_UNORM && 270 (buffers & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) { 271 zmask_clear = FALSE; 272 hiz_clear = FALSE; 273 } else { 274 zmask_clear = r300_fast_zclear_allowed(r300, buffers); 275 hiz_clear = r300_hiz_clear_allowed(r300); 276 } 277 278 /* If we need Hyper-Z. */ 279 if (zmask_clear || hiz_clear) { 280 /* Try to obtain the access to Hyper-Z buffers if we don't have one. */ 281 if (!r300->hyperz_enabled && 282 (r300->screen->caps.is_r500 || debug_get_option_hyperz())) { 283 r300->hyperz_enabled = 284 r300->rws->cs_request_feature(&r300->cs, 285 RADEON_FID_R300_HYPERZ_ACCESS, 286 TRUE); 287 if (r300->hyperz_enabled) { 288 /* Need to emit HyperZ buffer regs for the first time. */ 289 r300_mark_fb_state_dirty(r300, R300_CHANGED_HYPERZ_FLAG); 290 } 291 } 292 293 /* Setup Hyper-Z clears. */ 294 if (r300->hyperz_enabled) { 295 if (zmask_clear) { 296 hyperz_dcv = hyperz->zb_depthclearvalue = 297 r300_depth_clear_value(fb->zsbuf->format, depth, stencil); 298 299 r300_mark_atom_dirty(r300, &r300->zmask_clear); 300 r300_mark_atom_dirty(r300, &r300->gpu_flush); 301 buffers &= ~PIPE_CLEAR_DEPTHSTENCIL; 302 } 303 304 if (hiz_clear) { 305 r300->hiz_clear_value = r300_hiz_clear_value(depth); 306 r300_mark_atom_dirty(r300, &r300->hiz_clear); 307 r300_mark_atom_dirty(r300, &r300->gpu_flush); 308 } 309 r300->num_z_clears++; 310 } 311 } 312 } 313 314 /* Use fast color clear for an AA colorbuffer. 315 * The CMASK is shared between all colorbuffers, so we use it 316 * if there is only one colorbuffer bound. */ 317 if ((buffers & PIPE_CLEAR_COLOR) && fb->nr_cbufs == 1 && fb->cbufs[0] && 318 r300_resource(fb->cbufs[0]->texture)->tex.cmask_dwords) { 319 /* Try to obtain the access to the CMASK if we don't have one. */ 320 if (!r300->cmask_access) { 321 r300->cmask_access = 322 r300->rws->cs_request_feature(&r300->cs, 323 RADEON_FID_R300_CMASK_ACCESS, 324 TRUE); 325 } 326 327 /* Setup the clear. */ 328 if (r300->cmask_access) { 329 /* Pair the resource with the CMASK to avoid other resources 330 * accessing it. */ 331 if (!r300->screen->cmask_resource) { 332 mtx_lock(&r300->screen->cmask_mutex); 333 /* Double checking (first unlocked, then locked). */ 334 if (!r300->screen->cmask_resource) { 335 /* Don't reference this, so that the texture can be 336 * destroyed while set in cmask_resource. 337 * Then in texture_destroy, we set cmask_resource to NULL. */ 338 r300->screen->cmask_resource = fb->cbufs[0]->texture; 339 } 340 mtx_unlock(&r300->screen->cmask_mutex); 341 } 342 343 if (r300->screen->cmask_resource == fb->cbufs[0]->texture) { 344 r300_set_clear_color(r300, color); 345 r300_mark_atom_dirty(r300, &r300->cmask_clear); 346 r300_mark_atom_dirty(r300, &r300->gpu_flush); 347 buffers &= ~PIPE_CLEAR_COLOR; 348 } 349 } 350 } 351 /* Enable CBZB clear. */ 352 else if (r300_cbzb_clear_allowed(r300, buffers)) { 353 struct r300_surface *surf = r300_surface(fb->cbufs[0]); 354 355 hyperz->zb_depthclearvalue = 356 r300_depth_clear_cb_value(surf->base.format, color->f); 357 358 width = surf->cbzb_width; 359 height = surf->cbzb_height; 360 361 r300->cbzb_clear = TRUE; 362 r300_mark_fb_state_dirty(r300, R300_CHANGED_HYPERZ_FLAG); 363 } 364 365 /* Clear. */ 366 if (buffers) { 367 /* Clear using the blitter. */ 368 r300_blitter_begin(r300, R300_CLEAR); 369 util_blitter_clear(r300->blitter, width, height, 1, 370 buffers, color, depth, stencil, 371 util_framebuffer_get_num_samples(fb) > 1); 372 r300_blitter_end(r300); 373 } else if (r300->zmask_clear.dirty || 374 r300->hiz_clear.dirty || 375 r300->cmask_clear.dirty) { 376 /* Just clear zmask and hiz now, this does not use the standard draw 377 * procedure. */ 378 /* Calculate zmask_clear and hiz_clear atom sizes. */ 379 unsigned dwords = 380 r300->gpu_flush.size + 381 (r300->zmask_clear.dirty ? r300->zmask_clear.size : 0) + 382 (r300->hiz_clear.dirty ? r300->hiz_clear.size : 0) + 383 (r300->cmask_clear.dirty ? r300->cmask_clear.size : 0) + 384 r300_get_num_cs_end_dwords(r300); 385 386 /* Reserve CS space. */ 387 if (!r300->rws->cs_check_space(&r300->cs, dwords, false)) { 388 r300_flush(&r300->context, PIPE_FLUSH_ASYNC, NULL); 389 } 390 391 /* Emit clear packets. */ 392 r300_emit_gpu_flush(r300, r300->gpu_flush.size, r300->gpu_flush.state); 393 r300->gpu_flush.dirty = FALSE; 394 395 if (r300->zmask_clear.dirty) { 396 r300_emit_zmask_clear(r300, r300->zmask_clear.size, 397 r300->zmask_clear.state); 398 r300->zmask_clear.dirty = FALSE; 399 } 400 if (r300->hiz_clear.dirty) { 401 r300_emit_hiz_clear(r300, r300->hiz_clear.size, 402 r300->hiz_clear.state); 403 r300->hiz_clear.dirty = FALSE; 404 } 405 if (r300->cmask_clear.dirty) { 406 r300_emit_cmask_clear(r300, r300->cmask_clear.size, 407 r300->cmask_clear.state); 408 r300->cmask_clear.dirty = FALSE; 409 } 410 } else { 411 assert(0); 412 } 413 414 /* Disable CBZB clear. */ 415 if (r300->cbzb_clear) { 416 r300->cbzb_clear = FALSE; 417 hyperz->zb_depthclearvalue = hyperz_dcv; 418 r300_mark_fb_state_dirty(r300, R300_CHANGED_HYPERZ_FLAG); 419 } 420 421 /* Enable fastfill and/or hiz. 422 * 423 * If we cleared zmask/hiz, it's in use now. The Hyper-Z state update 424 * looks if zmask/hiz is in use and programs hardware accordingly. */ 425 if (r300->zmask_in_use || r300->hiz_in_use) { 426 r300_mark_atom_dirty(r300, &r300->hyperz_state); 427 } 428} 429 430/* Clear a region of a color surface to a constant value. */ 431static void r300_clear_render_target(struct pipe_context *pipe, 432 struct pipe_surface *dst, 433 const union pipe_color_union *color, 434 unsigned dstx, unsigned dsty, 435 unsigned width, unsigned height, 436 bool render_condition_enabled) 437{ 438 struct r300_context *r300 = r300_context(pipe); 439 440 r300_blitter_begin(r300, R300_CLEAR_SURFACE | 441 (render_condition_enabled ? 0 : R300_IGNORE_RENDER_COND)); 442 util_blitter_clear_render_target(r300->blitter, dst, color, 443 dstx, dsty, width, height); 444 r300_blitter_end(r300); 445} 446 447/* Clear a region of a depth stencil surface. */ 448static void r300_clear_depth_stencil(struct pipe_context *pipe, 449 struct pipe_surface *dst, 450 unsigned clear_flags, 451 double depth, 452 unsigned stencil, 453 unsigned dstx, unsigned dsty, 454 unsigned width, unsigned height, 455 bool render_condition_enabled) 456{ 457 struct r300_context *r300 = r300_context(pipe); 458 struct pipe_framebuffer_state *fb = 459 (struct pipe_framebuffer_state*)r300->fb_state.state; 460 461 if (r300->zmask_in_use && !r300->locked_zbuffer) { 462 if (fb->zsbuf->texture == dst->texture) { 463 r300_decompress_zmask(r300); 464 } 465 } 466 467 /* XXX Do not decompress ZMask of the currently-set zbuffer. */ 468 r300_blitter_begin(r300, R300_CLEAR_SURFACE | 469 (render_condition_enabled ? 0 : R300_IGNORE_RENDER_COND)); 470 util_blitter_clear_depth_stencil(r300->blitter, dst, clear_flags, depth, stencil, 471 dstx, dsty, width, height); 472 r300_blitter_end(r300); 473} 474 475void r300_decompress_zmask(struct r300_context *r300) 476{ 477 struct pipe_framebuffer_state *fb = 478 (struct pipe_framebuffer_state*)r300->fb_state.state; 479 480 if (!r300->zmask_in_use || r300->locked_zbuffer) 481 return; 482 483 r300->zmask_decompress = TRUE; 484 r300_mark_atom_dirty(r300, &r300->hyperz_state); 485 486 r300_blitter_begin(r300, R300_DECOMPRESS); 487 util_blitter_custom_clear_depth(r300->blitter, fb->width, fb->height, 0, 488 r300->dsa_decompress_zmask); 489 r300_blitter_end(r300); 490 491 r300->zmask_decompress = FALSE; 492 r300->zmask_in_use = FALSE; 493 r300_mark_atom_dirty(r300, &r300->hyperz_state); 494} 495 496void r300_decompress_zmask_locked_unsafe(struct r300_context *r300) 497{ 498 struct pipe_framebuffer_state fb; 499 500 memset(&fb, 0, sizeof(fb)); 501 fb.width = r300->locked_zbuffer->width; 502 fb.height = r300->locked_zbuffer->height; 503 fb.zsbuf = r300->locked_zbuffer; 504 505 r300->context.set_framebuffer_state(&r300->context, &fb); 506 r300_decompress_zmask(r300); 507} 508 509void r300_decompress_zmask_locked(struct r300_context *r300) 510{ 511 struct pipe_framebuffer_state saved_fb; 512 513 memset(&saved_fb, 0, sizeof(saved_fb)); 514 util_copy_framebuffer_state(&saved_fb, r300->fb_state.state); 515 r300_decompress_zmask_locked_unsafe(r300); 516 r300->context.set_framebuffer_state(&r300->context, &saved_fb); 517 util_unreference_framebuffer_state(&saved_fb); 518 519 pipe_surface_reference(&r300->locked_zbuffer, NULL); 520} 521 522bool r300_is_blit_supported(enum pipe_format format) 523{ 524 const struct util_format_description *desc = 525 util_format_description(format); 526 527 return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN || 528 desc->layout == UTIL_FORMAT_LAYOUT_S3TC || 529 desc->layout == UTIL_FORMAT_LAYOUT_RGTC; 530} 531 532/* Copy a block of pixels from one surface to another. */ 533static void r300_resource_copy_region(struct pipe_context *pipe, 534 struct pipe_resource *dst, 535 unsigned dst_level, 536 unsigned dstx, unsigned dsty, unsigned dstz, 537 struct pipe_resource *src, 538 unsigned src_level, 539 const struct pipe_box *src_box) 540{ 541 struct pipe_screen *screen = pipe->screen; 542 struct r300_context *r300 = r300_context(pipe); 543 struct pipe_framebuffer_state *fb = 544 (struct pipe_framebuffer_state*)r300->fb_state.state; 545 unsigned src_width0 = r300_resource(src)->tex.width0; 546 unsigned src_height0 = r300_resource(src)->tex.height0; 547 unsigned dst_width0 = r300_resource(dst)->tex.width0; 548 unsigned dst_height0 = r300_resource(dst)->tex.height0; 549 unsigned layout; 550 struct pipe_box box, dstbox; 551 struct pipe_sampler_view src_templ, *src_view; 552 struct pipe_surface dst_templ, *dst_view; 553 554 /* Fallback for buffers. */ 555 if ((dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) || 556 !r300_is_blit_supported(dst->format)) { 557 util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, 558 src, src_level, src_box); 559 return; 560 } 561 562 /* Can't read MSAA textures. */ 563 if (src->nr_samples > 1 || dst->nr_samples > 1) { 564 return; 565 } 566 567 /* The code below changes the texture format so that the copy can be done 568 * on hardware. E.g. depth-stencil surfaces are copied as RGBA 569 * colorbuffers. */ 570 571 util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz); 572 util_blitter_default_src_texture(r300->blitter, &src_templ, src, src_level); 573 574 layout = util_format_description(dst_templ.format)->layout; 575 576 /* Handle non-renderable plain formats. */ 577 if (layout == UTIL_FORMAT_LAYOUT_PLAIN && 578 (!screen->is_format_supported(screen, src_templ.format, src->target, 579 src->nr_samples, src->nr_storage_samples, 580 PIPE_BIND_SAMPLER_VIEW) || 581 !screen->is_format_supported(screen, dst_templ.format, dst->target, 582 dst->nr_samples, dst->nr_storage_samples, 583 PIPE_BIND_RENDER_TARGET))) { 584 switch (util_format_get_blocksize(dst_templ.format)) { 585 case 1: 586 dst_templ.format = PIPE_FORMAT_I8_UNORM; 587 break; 588 case 2: 589 dst_templ.format = PIPE_FORMAT_B4G4R4A4_UNORM; 590 break; 591 case 4: 592 dst_templ.format = PIPE_FORMAT_B8G8R8A8_UNORM; 593 break; 594 case 8: 595 dst_templ.format = PIPE_FORMAT_R16G16B16A16_UNORM; 596 break; 597 default: 598 debug_printf("r300: copy_region: Unhandled format: %s. Falling back to software.\n" 599 "r300: copy_region: Software fallback doesn't work for tiled textures.\n", 600 util_format_short_name(dst_templ.format)); 601 } 602 src_templ.format = dst_templ.format; 603 } 604 605 /* Handle compressed formats. */ 606 if (layout == UTIL_FORMAT_LAYOUT_S3TC || 607 layout == UTIL_FORMAT_LAYOUT_RGTC) { 608 assert(src_templ.format == dst_templ.format); 609 610 box = *src_box; 611 src_box = &box; 612 613 dst_width0 = align(dst_width0, 4); 614 dst_height0 = align(dst_height0, 4); 615 src_width0 = align(src_width0, 4); 616 src_height0 = align(src_height0, 4); 617 box.width = align(box.width, 4); 618 box.height = align(box.height, 4); 619 620 switch (util_format_get_blocksize(dst_templ.format)) { 621 case 8: 622 /* one 4x4 pixel block has 8 bytes. 623 * we set 1 pixel = 4 bytes ===> 1 block corrensponds to 2 pixels. */ 624 dst_templ.format = PIPE_FORMAT_R8G8B8A8_UNORM; 625 dst_width0 = dst_width0 / 2; 626 src_width0 = src_width0 / 2; 627 dstx /= 2; 628 box.x /= 2; 629 box.width /= 2; 630 break; 631 case 16: 632 /* one 4x4 pixel block has 16 bytes. 633 * we set 1 pixel = 4 bytes ===> 1 block corresponds to 4 pixels. */ 634 dst_templ.format = PIPE_FORMAT_R8G8B8A8_UNORM; 635 break; 636 } 637 src_templ.format = dst_templ.format; 638 639 dst_height0 = dst_height0 / 4; 640 src_height0 = src_height0 / 4; 641 dsty /= 4; 642 box.y /= 4; 643 box.height /= 4; 644 } 645 646 /* Fallback for textures. */ 647 if (!screen->is_format_supported(screen, dst_templ.format, 648 dst->target, dst->nr_samples, 649 dst->nr_storage_samples, 650 PIPE_BIND_RENDER_TARGET) || 651 !screen->is_format_supported(screen, src_templ.format, 652 src->target, src->nr_samples, 653 src->nr_storage_samples, 654 PIPE_BIND_SAMPLER_VIEW)) { 655 assert(0 && "this shouldn't happen, update r300_is_blit_supported"); 656 util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, 657 src, src_level, src_box); 658 return; 659 } 660 661 /* Decompress ZMASK. */ 662 if (r300->zmask_in_use && !r300->locked_zbuffer) { 663 if (fb->zsbuf->texture == src || 664 fb->zsbuf->texture == dst) { 665 r300_decompress_zmask(r300); 666 } 667 } 668 669 dst_view = r300_create_surface_custom(pipe, dst, &dst_templ, dst_width0, dst_height0); 670 src_view = r300_create_sampler_view_custom(pipe, src, &src_templ, src_width0, src_height0); 671 672 u_box_3d(dstx, dsty, dstz, abs(src_box->width), abs(src_box->height), 673 abs(src_box->depth), &dstbox); 674 675 r300_blitter_begin(r300, R300_COPY); 676 util_blitter_blit_generic(r300->blitter, dst_view, &dstbox, 677 src_view, src_box, src_width0, src_height0, 678 PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL, 679 FALSE, FALSE); 680 r300_blitter_end(r300); 681 682 pipe_surface_reference(&dst_view, NULL); 683 pipe_sampler_view_reference(&src_view, NULL); 684} 685 686static boolean r300_is_simple_msaa_resolve(const struct pipe_blit_info *info) 687{ 688 unsigned dst_width = u_minify(info->dst.resource->width0, info->dst.level); 689 unsigned dst_height = u_minify(info->dst.resource->height0, info->dst.level); 690 691 return info->src.resource->nr_samples > 1 && 692 info->dst.resource->nr_samples <= 1 && 693 info->dst.resource->format == info->src.resource->format && 694 info->dst.resource->format == info->dst.format && 695 info->src.resource->format == info->src.format && 696 !info->scissor_enable && 697 info->mask == PIPE_MASK_RGBA && 698 dst_width == info->src.resource->width0 && 699 dst_height == info->src.resource->height0 && 700 info->dst.box.x == 0 && 701 info->dst.box.y == 0 && 702 info->dst.box.width == dst_width && 703 info->dst.box.height == dst_height && 704 info->src.box.x == 0 && 705 info->src.box.y == 0 && 706 info->src.box.width == dst_width && 707 info->src.box.height == dst_height && 708 (r300_resource(info->dst.resource)->tex.microtile != RADEON_LAYOUT_LINEAR || 709 r300_resource(info->dst.resource)->tex.macrotile[info->dst.level] != RADEON_LAYOUT_LINEAR); 710} 711 712static void r300_simple_msaa_resolve(struct pipe_context *pipe, 713 struct pipe_resource *dst, 714 unsigned dst_level, 715 unsigned dst_layer, 716 struct pipe_resource *src, 717 enum pipe_format format) 718{ 719 struct r300_context *r300 = r300_context(pipe); 720 struct r300_surface *srcsurf, *dstsurf; 721 struct pipe_surface surf_tmpl; 722 struct r300_aa_state *aa = (struct r300_aa_state*)r300->aa_state.state; 723 724 memset(&surf_tmpl, 0, sizeof(surf_tmpl)); 725 surf_tmpl.format = format; 726 srcsurf = r300_surface(pipe->create_surface(pipe, src, &surf_tmpl)); 727 728 surf_tmpl.format = format; 729 surf_tmpl.u.tex.level = dst_level; 730 surf_tmpl.u.tex.first_layer = 731 surf_tmpl.u.tex.last_layer = dst_layer; 732 dstsurf = r300_surface(pipe->create_surface(pipe, dst, &surf_tmpl)); 733 734 /* COLORPITCH should contain the tiling info of the resolve buffer. 735 * The tiling of the AA buffer isn't programmable anyway. */ 736 srcsurf->pitch &= ~(R300_COLOR_TILE(1) | R300_COLOR_MICROTILE(3)); 737 srcsurf->pitch |= dstsurf->pitch & (R300_COLOR_TILE(1) | R300_COLOR_MICROTILE(3)); 738 739 /* Enable AA resolve. */ 740 aa->dest = dstsurf; 741 r300->aa_state.size = 8; 742 r300_mark_atom_dirty(r300, &r300->aa_state); 743 744 /* Resolve the surface. */ 745 r300_blitter_begin(r300, R300_CLEAR_SURFACE); 746 util_blitter_custom_color(r300->blitter, &srcsurf->base, NULL); 747 r300_blitter_end(r300); 748 749 /* Disable AA resolve. */ 750 aa->dest = NULL; 751 r300->aa_state.size = 4; 752 r300_mark_atom_dirty(r300, &r300->aa_state); 753 754 pipe_surface_reference((struct pipe_surface**)&srcsurf, NULL); 755 pipe_surface_reference((struct pipe_surface**)&dstsurf, NULL); 756} 757 758static void r300_msaa_resolve(struct pipe_context *pipe, 759 const struct pipe_blit_info *info) 760{ 761 struct r300_context *r300 = r300_context(pipe); 762 struct pipe_screen *screen = pipe->screen; 763 struct pipe_resource *tmp, templ; 764 struct pipe_blit_info blit; 765 766 assert(info->src.level == 0); 767 assert(info->src.box.z == 0); 768 assert(info->src.box.depth == 1); 769 assert(info->dst.box.depth == 1); 770 771 if (r300_is_simple_msaa_resolve(info)) { 772 r300_simple_msaa_resolve(pipe, info->dst.resource, info->dst.level, 773 info->dst.box.z, info->src.resource, 774 info->src.format); 775 return; 776 } 777 778 /* resolve into a temporary texture, then blit */ 779 memset(&templ, 0, sizeof(templ)); 780 templ.target = PIPE_TEXTURE_2D; 781 templ.format = info->src.resource->format; 782 templ.width0 = info->src.resource->width0; 783 templ.height0 = info->src.resource->height0; 784 templ.depth0 = 1; 785 templ.array_size = 1; 786 templ.usage = PIPE_USAGE_DEFAULT; 787 templ.flags = R300_RESOURCE_FORCE_MICROTILING; 788 789 tmp = screen->resource_create(screen, &templ); 790 791 /* resolve */ 792 r300_simple_msaa_resolve(pipe, tmp, 0, 0, info->src.resource, 793 info->src.format); 794 795 /* blit */ 796 blit = *info; 797 blit.src.resource = tmp; 798 blit.src.box.z = 0; 799 800 r300_blitter_begin(r300, R300_BLIT | R300_IGNORE_RENDER_COND); 801 util_blitter_blit(r300->blitter, &blit); 802 r300_blitter_end(r300); 803 804 pipe_resource_reference(&tmp, NULL); 805} 806 807static void r300_blit(struct pipe_context *pipe, 808 const struct pipe_blit_info *blit) 809{ 810 struct r300_context *r300 = r300_context(pipe); 811 struct pipe_framebuffer_state *fb = 812 (struct pipe_framebuffer_state*)r300->fb_state.state; 813 struct pipe_blit_info info = *blit; 814 815 /* The driver supports sRGB textures but not framebuffers. Blitting 816 * from sRGB to sRGB should be the same as blitting from linear 817 * to linear, so use that, This avoids incorrect linearization. 818 */ 819 if (util_format_is_srgb(info.src.format)) { 820 info.src.format = util_format_linear(info.src.format); 821 info.dst.format = util_format_linear(info.dst.format); 822 } 823 824 /* MSAA resolve. */ 825 if (info.src.resource->nr_samples > 1 && 826 !util_format_is_depth_or_stencil(info.src.resource->format)) { 827 r300_msaa_resolve(pipe, &info); 828 return; 829 } 830 831 /* Can't read MSAA textures. */ 832 if (info.src.resource->nr_samples > 1) { 833 return; 834 } 835 836 /* Blit a combined depth-stencil resource as color. 837 * S8Z24 is the only supported stencil format. */ 838 if ((info.mask & PIPE_MASK_S) && 839 info.src.format == PIPE_FORMAT_S8_UINT_Z24_UNORM && 840 info.dst.format == PIPE_FORMAT_S8_UINT_Z24_UNORM) { 841 if (info.dst.resource->nr_samples > 1) { 842 /* Cannot do that with MSAA buffers. */ 843 info.mask &= ~PIPE_MASK_S; 844 if (!(info.mask & PIPE_MASK_Z)) { 845 return; 846 } 847 } else { 848 /* Single-sample buffer. */ 849 info.src.format = PIPE_FORMAT_B8G8R8A8_UNORM; 850 info.dst.format = PIPE_FORMAT_B8G8R8A8_UNORM; 851 if (info.mask & PIPE_MASK_Z) { 852 info.mask = PIPE_MASK_RGBA; /* depth+stencil */ 853 } else { 854 info.mask = PIPE_MASK_B; /* stencil only */ 855 } 856 } 857 } 858 859 /* Decompress ZMASK. */ 860 if (r300->zmask_in_use && !r300->locked_zbuffer) { 861 if (fb->zsbuf->texture == info.src.resource || 862 fb->zsbuf->texture == info.dst.resource) { 863 r300_decompress_zmask(r300); 864 } 865 } 866 867 r300_blitter_begin(r300, R300_BLIT | 868 (info.render_condition_enable ? 0 : R300_IGNORE_RENDER_COND)); 869 util_blitter_blit(r300->blitter, &info); 870 r300_blitter_end(r300); 871} 872 873static void r300_flush_resource(struct pipe_context *ctx, 874 struct pipe_resource *resource) 875{ 876} 877 878void r300_init_blit_functions(struct r300_context *r300) 879{ 880 r300->context.clear = r300_clear; 881 r300->context.clear_render_target = r300_clear_render_target; 882 r300->context.clear_depth_stencil = r300_clear_depth_stencil; 883 r300->context.resource_copy_region = r300_resource_copy_region; 884 r300->context.blit = r300_blit; 885 r300->context.flush_resource = r300_flush_resource; 886} 887