1848b8605Smrg/* 2848b8605Smrg * Copyright 2009 Marek Olšák <maraeo@gmail.com> 3848b8605Smrg * 4848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5848b8605Smrg * copy of this software and associated documentation files (the "Software"), 6848b8605Smrg * to deal in the Software without restriction, including without limitation 7848b8605Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub 8848b8605Smrg * license, and/or sell copies of the Software, and to permit persons to whom 9848b8605Smrg * the Software is furnished to do so, subject to the following conditions: 10848b8605Smrg * 11848b8605Smrg * The above copyright notice and this permission notice (including the next 12848b8605Smrg * paragraph) shall be included in all copies or substantial portions of the 13848b8605Smrg * Software. 14848b8605Smrg * 15848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18848b8605Smrg * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19848b8605Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20848b8605Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21848b8605Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 22848b8605Smrg 23848b8605Smrg#include "r300_context.h" 24848b8605Smrg#include "r300_emit.h" 25848b8605Smrg#include "r300_texture.h" 26848b8605Smrg#include "r300_reg.h" 27848b8605Smrg 28848b8605Smrg#include "util/u_format.h" 29848b8605Smrg#include "util/u_half.h" 30848b8605Smrg#include "util/u_pack_color.h" 31848b8605Smrg#include "util/u_surface.h" 32848b8605Smrg 33848b8605Smrgenum r300_blitter_op /* bitmask */ 34848b8605Smrg{ 35848b8605Smrg R300_STOP_QUERY = 1, 36848b8605Smrg R300_SAVE_TEXTURES = 2, 37848b8605Smrg R300_SAVE_FRAMEBUFFER = 4, 38848b8605Smrg R300_IGNORE_RENDER_COND = 8, 39848b8605Smrg 40848b8605Smrg R300_CLEAR = R300_STOP_QUERY, 41848b8605Smrg 42848b8605Smrg R300_CLEAR_SURFACE = R300_STOP_QUERY | R300_SAVE_FRAMEBUFFER, 43848b8605Smrg 44848b8605Smrg R300_COPY = R300_STOP_QUERY | R300_SAVE_FRAMEBUFFER | 45848b8605Smrg R300_SAVE_TEXTURES | R300_IGNORE_RENDER_COND, 46848b8605Smrg 47848b8605Smrg R300_BLIT = R300_STOP_QUERY | R300_SAVE_FRAMEBUFFER | 48848b8605Smrg R300_SAVE_TEXTURES, 49848b8605Smrg 50848b8605Smrg R300_DECOMPRESS = R300_STOP_QUERY | R300_IGNORE_RENDER_COND, 51848b8605Smrg}; 52848b8605Smrg 53848b8605Smrgstatic void r300_blitter_begin(struct r300_context* r300, enum r300_blitter_op op) 54848b8605Smrg{ 55848b8605Smrg if ((op & R300_STOP_QUERY) && r300->query_current) { 56848b8605Smrg r300->blitter_saved_query = r300->query_current; 57848b8605Smrg r300_stop_query(r300); 58848b8605Smrg } 59848b8605Smrg 60848b8605Smrg /* Yeah we have to save all those states to ensure the blitter operation 61848b8605Smrg * is really transparent. The states will be restored by the blitter once 62848b8605Smrg * copying is done. */ 63848b8605Smrg util_blitter_save_blend(r300->blitter, r300->blend_state.state); 64848b8605Smrg util_blitter_save_depth_stencil_alpha(r300->blitter, r300->dsa_state.state); 65848b8605Smrg util_blitter_save_stencil_ref(r300->blitter, &(r300->stencil_ref)); 66848b8605Smrg util_blitter_save_rasterizer(r300->blitter, r300->rs_state.state); 67848b8605Smrg util_blitter_save_fragment_shader(r300->blitter, r300->fs.state); 68848b8605Smrg util_blitter_save_vertex_shader(r300->blitter, r300->vs_state.state); 69848b8605Smrg util_blitter_save_viewport(r300->blitter, &r300->viewport); 70848b8605Smrg util_blitter_save_scissor(r300->blitter, r300->scissor_state.state); 71848b8605Smrg util_blitter_save_sample_mask(r300->blitter, *(unsigned*)r300->sample_mask.state); 72848b8605Smrg util_blitter_save_vertex_buffer_slot(r300->blitter, r300->vertex_buffer); 73848b8605Smrg util_blitter_save_vertex_elements(r300->blitter, r300->velems); 74848b8605Smrg 75848b8605Smrg if (op & R300_SAVE_FRAMEBUFFER) { 76848b8605Smrg util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state); 77848b8605Smrg } 78848b8605Smrg 79848b8605Smrg if (op & R300_SAVE_TEXTURES) { 80848b8605Smrg struct r300_textures_state* state = 81848b8605Smrg (struct r300_textures_state*)r300->textures_state.state; 82848b8605Smrg 83848b8605Smrg util_blitter_save_fragment_sampler_states( 84848b8605Smrg r300->blitter, state->sampler_state_count, 85848b8605Smrg (void**)state->sampler_states); 86848b8605Smrg 87848b8605Smrg util_blitter_save_fragment_sampler_views( 88848b8605Smrg r300->blitter, state->sampler_view_count, 89848b8605Smrg (struct pipe_sampler_view**)state->sampler_views); 90848b8605Smrg } 91848b8605Smrg 92848b8605Smrg if (op & R300_IGNORE_RENDER_COND) { 93848b8605Smrg /* Save the flag. */ 94848b8605Smrg r300->blitter_saved_skip_rendering = r300->skip_rendering+1; 95848b8605Smrg r300->skip_rendering = FALSE; 96848b8605Smrg } else { 97848b8605Smrg r300->blitter_saved_skip_rendering = 0; 98848b8605Smrg } 99848b8605Smrg} 100848b8605Smrg 101848b8605Smrgstatic void r300_blitter_end(struct r300_context *r300) 102848b8605Smrg{ 103848b8605Smrg if (r300->blitter_saved_query) { 104848b8605Smrg r300_resume_query(r300, r300->blitter_saved_query); 105848b8605Smrg r300->blitter_saved_query = NULL; 106848b8605Smrg } 107848b8605Smrg 108848b8605Smrg if (r300->blitter_saved_skip_rendering) { 109848b8605Smrg /* Restore the flag. */ 110848b8605Smrg r300->skip_rendering = r300->blitter_saved_skip_rendering-1; 111848b8605Smrg } 112848b8605Smrg} 113848b8605Smrg 114848b8605Smrgstatic uint32_t r300_depth_clear_cb_value(enum pipe_format format, 115848b8605Smrg const float* rgba) 116848b8605Smrg{ 117848b8605Smrg union util_color uc; 118848b8605Smrg util_pack_color(rgba, format, &uc); 119848b8605Smrg 120848b8605Smrg if (util_format_get_blocksizebits(format) == 32) 121848b8605Smrg return uc.ui[0]; 122848b8605Smrg else 123848b8605Smrg return uc.us | (uc.us << 16); 124848b8605Smrg} 125848b8605Smrg 126848b8605Smrgstatic boolean r300_cbzb_clear_allowed(struct r300_context *r300, 127848b8605Smrg unsigned clear_buffers) 128848b8605Smrg{ 129848b8605Smrg struct pipe_framebuffer_state *fb = 130848b8605Smrg (struct pipe_framebuffer_state*)r300->fb_state.state; 131848b8605Smrg 132848b8605Smrg /* Only color clear allowed, and only one colorbuffer. */ 133848b8605Smrg if ((clear_buffers & ~PIPE_CLEAR_COLOR) != 0 || fb->nr_cbufs != 1 || !fb->cbufs[0]) 134848b8605Smrg return FALSE; 135848b8605Smrg 136848b8605Smrg return r300_surface(fb->cbufs[0])->cbzb_allowed; 137848b8605Smrg} 138848b8605Smrg 139848b8605Smrgstatic boolean r300_fast_zclear_allowed(struct r300_context *r300, 140848b8605Smrg unsigned clear_buffers) 141848b8605Smrg{ 142848b8605Smrg struct pipe_framebuffer_state *fb = 143848b8605Smrg (struct pipe_framebuffer_state*)r300->fb_state.state; 144848b8605Smrg 145848b8605Smrg return r300_resource(fb->zsbuf->texture)->tex.zmask_dwords[fb->zsbuf->u.tex.level] != 0; 146848b8605Smrg} 147848b8605Smrg 148848b8605Smrgstatic boolean r300_hiz_clear_allowed(struct r300_context *r300) 149848b8605Smrg{ 150848b8605Smrg struct pipe_framebuffer_state *fb = 151848b8605Smrg (struct pipe_framebuffer_state*)r300->fb_state.state; 152848b8605Smrg 153848b8605Smrg return r300_resource(fb->zsbuf->texture)->tex.hiz_dwords[fb->zsbuf->u.tex.level] != 0; 154848b8605Smrg} 155848b8605Smrg 156848b8605Smrgstatic uint32_t r300_depth_clear_value(enum pipe_format format, 157848b8605Smrg double depth, unsigned stencil) 158848b8605Smrg{ 159848b8605Smrg switch (format) { 160848b8605Smrg case PIPE_FORMAT_Z16_UNORM: 161848b8605Smrg case PIPE_FORMAT_X8Z24_UNORM: 162848b8605Smrg return util_pack_z(format, depth); 163848b8605Smrg 164848b8605Smrg case PIPE_FORMAT_S8_UINT_Z24_UNORM: 165848b8605Smrg return util_pack_z_stencil(format, depth, stencil); 166848b8605Smrg 167848b8605Smrg default: 168848b8605Smrg assert(0); 169848b8605Smrg return 0; 170848b8605Smrg } 171848b8605Smrg} 172848b8605Smrg 173848b8605Smrgstatic uint32_t r300_hiz_clear_value(double depth) 174848b8605Smrg{ 175848b8605Smrg uint32_t r = (uint32_t)(CLAMP(depth, 0, 1) * 255.5); 176848b8605Smrg assert(r <= 255); 177848b8605Smrg return r | (r << 8) | (r << 16) | (r << 24); 178848b8605Smrg} 179848b8605Smrg 180848b8605Smrgstatic void r300_set_clear_color(struct r300_context *r300, 181848b8605Smrg const union pipe_color_union *color) 182848b8605Smrg{ 183848b8605Smrg struct pipe_framebuffer_state *fb = 184848b8605Smrg (struct pipe_framebuffer_state*)r300->fb_state.state; 185848b8605Smrg union util_color uc; 186848b8605Smrg 187848b8605Smrg memset(&uc, 0, sizeof(uc)); 188848b8605Smrg util_pack_color(color->f, fb->cbufs[0]->format, &uc); 189848b8605Smrg 190848b8605Smrg if (fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT || 191848b8605Smrg fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16X16_FLOAT) { 192848b8605Smrg /* (0,1,2,3) maps to (B,G,R,A) */ 193848b8605Smrg r300->color_clear_value_gb = uc.h[0] | ((uint32_t)uc.h[1] << 16); 194848b8605Smrg r300->color_clear_value_ar = uc.h[2] | ((uint32_t)uc.h[3] << 16); 195848b8605Smrg } else { 196848b8605Smrg r300->color_clear_value = uc.ui[0]; 197848b8605Smrg } 198848b8605Smrg} 199848b8605Smrg 200848b8605SmrgDEBUG_GET_ONCE_BOOL_OPTION(hyperz, "RADEON_HYPERZ", FALSE) 201848b8605Smrg 202848b8605Smrg/* Clear currently bound buffers. */ 203848b8605Smrgstatic void r300_clear(struct pipe_context* pipe, 204848b8605Smrg unsigned buffers, 205848b8605Smrg const union pipe_color_union *color, 206848b8605Smrg double depth, 207848b8605Smrg unsigned stencil) 208848b8605Smrg{ 209848b8605Smrg /* My notes about Zbuffer compression: 210848b8605Smrg * 211848b8605Smrg * 1) The zbuffer must be micro-tiled and whole microtiles must be 212848b8605Smrg * written if compression is enabled. If microtiling is disabled, 213848b8605Smrg * it locks up. 214848b8605Smrg * 215848b8605Smrg * 2) There is ZMASK RAM which contains a compressed zbuffer. 216848b8605Smrg * Each dword of the Z Mask contains compression information 217848b8605Smrg * for 16 4x4 pixel tiles, that is 2 bits for each tile. 218848b8605Smrg * On chips with 2 Z pipes, every other dword maps to a different 219848b8605Smrg * pipe. On newer chipsets, there is a new compression mode 220848b8605Smrg * with 8x8 pixel tiles per 2 bits. 221848b8605Smrg * 222848b8605Smrg * 3) The FASTFILL bit has nothing to do with filling. It only tells hw 223848b8605Smrg * it should look in the ZMASK RAM first before fetching from a real 224848b8605Smrg * zbuffer. 225848b8605Smrg * 226848b8605Smrg * 4) If a pixel is in a cleared state, ZB_DEPTHCLEARVALUE is returned 227848b8605Smrg * during zbuffer reads instead of the value that is actually stored 228848b8605Smrg * in the zbuffer memory. A pixel is in a cleared state when its ZMASK 229848b8605Smrg * is equal to 0. Therefore, if you clear ZMASK with zeros, you may 230848b8605Smrg * leave the zbuffer memory uninitialized, but then you must enable 231848b8605Smrg * compression, so that the ZMASK RAM is actually used. 232848b8605Smrg * 233848b8605Smrg * 5) Each 4x4 (or 8x8) tile is automatically decompressed and recompressed 234848b8605Smrg * during zbuffer updates. A special decompressing operation should be 235848b8605Smrg * used to fully decompress a zbuffer, which basically just stores all 236848b8605Smrg * compressed tiles in ZMASK to the zbuffer memory. 237848b8605Smrg * 238848b8605Smrg * 6) For a 16-bit zbuffer, compression causes a hung with one or 239848b8605Smrg * two samples and should not be used. 240848b8605Smrg * 241848b8605Smrg * 7) FORCE_COMPRESSED_STENCIL_VALUE should be enabled for stencil clears 242848b8605Smrg * to avoid needless decompression. 243848b8605Smrg * 244848b8605Smrg * 8) Fastfill must not be used if reading of compressed Z data is disabled 245848b8605Smrg * and writing of compressed Z data is enabled (RD/WR_COMP_ENABLE), 246848b8605Smrg * i.e. it cannot be used to compress the zbuffer. 247848b8605Smrg * 248848b8605Smrg * 9) ZB_CB_CLEAR does not interact with zbuffer compression in any way. 249848b8605Smrg * 250848b8605Smrg * - Marek 251848b8605Smrg */ 252848b8605Smrg 253848b8605Smrg struct r300_context* r300 = r300_context(pipe); 254848b8605Smrg struct pipe_framebuffer_state *fb = 255848b8605Smrg (struct pipe_framebuffer_state*)r300->fb_state.state; 256848b8605Smrg struct r300_hyperz_state *hyperz = 257848b8605Smrg (struct r300_hyperz_state*)r300->hyperz_state.state; 258848b8605Smrg uint32_t width = fb->width; 259848b8605Smrg uint32_t height = fb->height; 260848b8605Smrg uint32_t hyperz_dcv = hyperz->zb_depthclearvalue; 261848b8605Smrg 262848b8605Smrg /* Use fast Z clear. 263848b8605Smrg * The zbuffer must be in micro-tiled mode, otherwise it locks up. */ 264848b8605Smrg if (buffers & PIPE_CLEAR_DEPTHSTENCIL) { 265848b8605Smrg boolean zmask_clear, hiz_clear; 266848b8605Smrg 267848b8605Smrg /* If both depth and stencil are present, they must be cleared together. */ 268848b8605Smrg if (fb->zsbuf->texture->format == PIPE_FORMAT_S8_UINT_Z24_UNORM && 269848b8605Smrg (buffers & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) { 270848b8605Smrg zmask_clear = FALSE; 271848b8605Smrg hiz_clear = FALSE; 272848b8605Smrg } else { 273848b8605Smrg zmask_clear = r300_fast_zclear_allowed(r300, buffers); 274848b8605Smrg hiz_clear = r300_hiz_clear_allowed(r300); 275848b8605Smrg } 276848b8605Smrg 277848b8605Smrg /* If we need Hyper-Z. */ 278848b8605Smrg if (zmask_clear || hiz_clear) { 279848b8605Smrg /* Try to obtain the access to Hyper-Z buffers if we don't have one. */ 280848b8605Smrg if (!r300->hyperz_enabled && 281848b8605Smrg (r300->screen->caps.is_r500 || debug_get_option_hyperz())) { 282848b8605Smrg r300->hyperz_enabled = 283848b8605Smrg r300->rws->cs_request_feature(r300->cs, 284848b8605Smrg RADEON_FID_R300_HYPERZ_ACCESS, 285848b8605Smrg TRUE); 286848b8605Smrg if (r300->hyperz_enabled) { 287848b8605Smrg /* Need to emit HyperZ buffer regs for the first time. */ 288848b8605Smrg r300_mark_fb_state_dirty(r300, R300_CHANGED_HYPERZ_FLAG); 289848b8605Smrg } 290848b8605Smrg } 291848b8605Smrg 292848b8605Smrg /* Setup Hyper-Z clears. */ 293848b8605Smrg if (r300->hyperz_enabled) { 294848b8605Smrg if (zmask_clear) { 295848b8605Smrg hyperz_dcv = hyperz->zb_depthclearvalue = 296848b8605Smrg r300_depth_clear_value(fb->zsbuf->format, depth, stencil); 297848b8605Smrg 298848b8605Smrg r300_mark_atom_dirty(r300, &r300->zmask_clear); 299848b8605Smrg r300_mark_atom_dirty(r300, &r300->gpu_flush); 300848b8605Smrg buffers &= ~PIPE_CLEAR_DEPTHSTENCIL; 301848b8605Smrg } 302848b8605Smrg 303848b8605Smrg if (hiz_clear) { 304848b8605Smrg r300->hiz_clear_value = r300_hiz_clear_value(depth); 305848b8605Smrg r300_mark_atom_dirty(r300, &r300->hiz_clear); 306848b8605Smrg r300_mark_atom_dirty(r300, &r300->gpu_flush); 307848b8605Smrg } 308848b8605Smrg r300->num_z_clears++; 309848b8605Smrg } 310848b8605Smrg } 311848b8605Smrg } 312848b8605Smrg 313848b8605Smrg /* Use fast color clear for an AA colorbuffer. 314848b8605Smrg * The CMASK is shared between all colorbuffers, so we use it 315848b8605Smrg * if there is only one colorbuffer bound. */ 316848b8605Smrg if ((buffers & PIPE_CLEAR_COLOR) && fb->nr_cbufs == 1 && fb->cbufs[0] && 317848b8605Smrg r300_resource(fb->cbufs[0]->texture)->tex.cmask_dwords) { 318848b8605Smrg /* Try to obtain the access to the CMASK if we don't have one. */ 319848b8605Smrg if (!r300->cmask_access) { 320848b8605Smrg r300->cmask_access = 321848b8605Smrg r300->rws->cs_request_feature(r300->cs, 322848b8605Smrg RADEON_FID_R300_CMASK_ACCESS, 323848b8605Smrg TRUE); 324848b8605Smrg } 325848b8605Smrg 326848b8605Smrg /* Setup the clear. */ 327848b8605Smrg if (r300->cmask_access) { 328848b8605Smrg /* Pair the resource with the CMASK to avoid other resources 329848b8605Smrg * accessing it. */ 330848b8605Smrg if (!r300->screen->cmask_resource) { 331b8e80941Smrg mtx_lock(&r300->screen->cmask_mutex); 332848b8605Smrg /* Double checking (first unlocked, then locked). */ 333848b8605Smrg if (!r300->screen->cmask_resource) { 334848b8605Smrg /* Don't reference this, so that the texture can be 335848b8605Smrg * destroyed while set in cmask_resource. 336848b8605Smrg * Then in texture_destroy, we set cmask_resource to NULL. */ 337848b8605Smrg r300->screen->cmask_resource = fb->cbufs[0]->texture; 338848b8605Smrg } 339b8e80941Smrg mtx_unlock(&r300->screen->cmask_mutex); 340848b8605Smrg } 341848b8605Smrg 342848b8605Smrg if (r300->screen->cmask_resource == fb->cbufs[0]->texture) { 343848b8605Smrg r300_set_clear_color(r300, color); 344848b8605Smrg r300_mark_atom_dirty(r300, &r300->cmask_clear); 345848b8605Smrg r300_mark_atom_dirty(r300, &r300->gpu_flush); 346848b8605Smrg buffers &= ~PIPE_CLEAR_COLOR; 347848b8605Smrg } 348848b8605Smrg } 349848b8605Smrg } 350848b8605Smrg /* Enable CBZB clear. */ 351848b8605Smrg else if (r300_cbzb_clear_allowed(r300, buffers)) { 352848b8605Smrg struct r300_surface *surf = r300_surface(fb->cbufs[0]); 353848b8605Smrg 354848b8605Smrg hyperz->zb_depthclearvalue = 355848b8605Smrg r300_depth_clear_cb_value(surf->base.format, color->f); 356848b8605Smrg 357848b8605Smrg width = surf->cbzb_width; 358848b8605Smrg height = surf->cbzb_height; 359848b8605Smrg 360848b8605Smrg r300->cbzb_clear = TRUE; 361848b8605Smrg r300_mark_fb_state_dirty(r300, R300_CHANGED_HYPERZ_FLAG); 362848b8605Smrg } 363848b8605Smrg 364848b8605Smrg /* Clear. */ 365848b8605Smrg if (buffers) { 366848b8605Smrg /* Clear using the blitter. */ 367848b8605Smrg r300_blitter_begin(r300, R300_CLEAR); 368848b8605Smrg util_blitter_clear(r300->blitter, width, height, 1, 369848b8605Smrg buffers, color, depth, stencil); 370848b8605Smrg r300_blitter_end(r300); 371848b8605Smrg } else if (r300->zmask_clear.dirty || 372848b8605Smrg r300->hiz_clear.dirty || 373848b8605Smrg r300->cmask_clear.dirty) { 374848b8605Smrg /* Just clear zmask and hiz now, this does not use the standard draw 375848b8605Smrg * procedure. */ 376848b8605Smrg /* Calculate zmask_clear and hiz_clear atom sizes. */ 377848b8605Smrg unsigned dwords = 378848b8605Smrg r300->gpu_flush.size + 379848b8605Smrg (r300->zmask_clear.dirty ? r300->zmask_clear.size : 0) + 380848b8605Smrg (r300->hiz_clear.dirty ? r300->hiz_clear.size : 0) + 381848b8605Smrg (r300->cmask_clear.dirty ? r300->cmask_clear.size : 0) + 382848b8605Smrg r300_get_num_cs_end_dwords(r300); 383848b8605Smrg 384848b8605Smrg /* Reserve CS space. */ 385b8e80941Smrg if (!r300->rws->cs_check_space(r300->cs, dwords)) { 386b8e80941Smrg r300_flush(&r300->context, PIPE_FLUSH_ASYNC, NULL); 387848b8605Smrg } 388848b8605Smrg 389848b8605Smrg /* Emit clear packets. */ 390848b8605Smrg r300_emit_gpu_flush(r300, r300->gpu_flush.size, r300->gpu_flush.state); 391848b8605Smrg r300->gpu_flush.dirty = FALSE; 392848b8605Smrg 393848b8605Smrg if (r300->zmask_clear.dirty) { 394848b8605Smrg r300_emit_zmask_clear(r300, r300->zmask_clear.size, 395848b8605Smrg r300->zmask_clear.state); 396848b8605Smrg r300->zmask_clear.dirty = FALSE; 397848b8605Smrg } 398848b8605Smrg if (r300->hiz_clear.dirty) { 399848b8605Smrg r300_emit_hiz_clear(r300, r300->hiz_clear.size, 400848b8605Smrg r300->hiz_clear.state); 401848b8605Smrg r300->hiz_clear.dirty = FALSE; 402848b8605Smrg } 403848b8605Smrg if (r300->cmask_clear.dirty) { 404848b8605Smrg r300_emit_cmask_clear(r300, r300->cmask_clear.size, 405848b8605Smrg r300->cmask_clear.state); 406848b8605Smrg r300->cmask_clear.dirty = FALSE; 407848b8605Smrg } 408848b8605Smrg } else { 409848b8605Smrg assert(0); 410848b8605Smrg } 411848b8605Smrg 412848b8605Smrg /* Disable CBZB clear. */ 413848b8605Smrg if (r300->cbzb_clear) { 414848b8605Smrg r300->cbzb_clear = FALSE; 415848b8605Smrg hyperz->zb_depthclearvalue = hyperz_dcv; 416848b8605Smrg r300_mark_fb_state_dirty(r300, R300_CHANGED_HYPERZ_FLAG); 417848b8605Smrg } 418848b8605Smrg 419848b8605Smrg /* Enable fastfill and/or hiz. 420848b8605Smrg * 421848b8605Smrg * If we cleared zmask/hiz, it's in use now. The Hyper-Z state update 422848b8605Smrg * looks if zmask/hiz is in use and programs hardware accordingly. */ 423848b8605Smrg if (r300->zmask_in_use || r300->hiz_in_use) { 424848b8605Smrg r300_mark_atom_dirty(r300, &r300->hyperz_state); 425848b8605Smrg } 426848b8605Smrg} 427848b8605Smrg 428848b8605Smrg/* Clear a region of a color surface to a constant value. */ 429848b8605Smrgstatic void r300_clear_render_target(struct pipe_context *pipe, 430848b8605Smrg struct pipe_surface *dst, 431848b8605Smrg const union pipe_color_union *color, 432848b8605Smrg unsigned dstx, unsigned dsty, 433b8e80941Smrg unsigned width, unsigned height, 434b8e80941Smrg bool render_condition_enabled) 435848b8605Smrg{ 436848b8605Smrg struct r300_context *r300 = r300_context(pipe); 437848b8605Smrg 438b8e80941Smrg r300_blitter_begin(r300, R300_CLEAR_SURFACE | 439b8e80941Smrg (render_condition_enabled ? 0 : R300_IGNORE_RENDER_COND)); 440848b8605Smrg util_blitter_clear_render_target(r300->blitter, dst, color, 441848b8605Smrg dstx, dsty, width, height); 442848b8605Smrg r300_blitter_end(r300); 443848b8605Smrg} 444848b8605Smrg 445848b8605Smrg/* Clear a region of a depth stencil surface. */ 446848b8605Smrgstatic void r300_clear_depth_stencil(struct pipe_context *pipe, 447848b8605Smrg struct pipe_surface *dst, 448848b8605Smrg unsigned clear_flags, 449848b8605Smrg double depth, 450848b8605Smrg unsigned stencil, 451848b8605Smrg unsigned dstx, unsigned dsty, 452b8e80941Smrg unsigned width, unsigned height, 453b8e80941Smrg bool render_condition_enabled) 454848b8605Smrg{ 455848b8605Smrg struct r300_context *r300 = r300_context(pipe); 456848b8605Smrg struct pipe_framebuffer_state *fb = 457848b8605Smrg (struct pipe_framebuffer_state*)r300->fb_state.state; 458848b8605Smrg 459848b8605Smrg if (r300->zmask_in_use && !r300->locked_zbuffer) { 460848b8605Smrg if (fb->zsbuf->texture == dst->texture) { 461848b8605Smrg r300_decompress_zmask(r300); 462848b8605Smrg } 463848b8605Smrg } 464848b8605Smrg 465848b8605Smrg /* XXX Do not decompress ZMask of the currently-set zbuffer. */ 466b8e80941Smrg r300_blitter_begin(r300, R300_CLEAR_SURFACE | 467b8e80941Smrg (render_condition_enabled ? 0 : R300_IGNORE_RENDER_COND)); 468848b8605Smrg util_blitter_clear_depth_stencil(r300->blitter, dst, clear_flags, depth, stencil, 469848b8605Smrg dstx, dsty, width, height); 470848b8605Smrg r300_blitter_end(r300); 471848b8605Smrg} 472848b8605Smrg 473848b8605Smrgvoid r300_decompress_zmask(struct r300_context *r300) 474848b8605Smrg{ 475848b8605Smrg struct pipe_framebuffer_state *fb = 476848b8605Smrg (struct pipe_framebuffer_state*)r300->fb_state.state; 477848b8605Smrg 478848b8605Smrg if (!r300->zmask_in_use || r300->locked_zbuffer) 479848b8605Smrg return; 480848b8605Smrg 481848b8605Smrg r300->zmask_decompress = TRUE; 482848b8605Smrg r300_mark_atom_dirty(r300, &r300->hyperz_state); 483848b8605Smrg 484848b8605Smrg r300_blitter_begin(r300, R300_DECOMPRESS); 485848b8605Smrg util_blitter_custom_clear_depth(r300->blitter, fb->width, fb->height, 0, 486848b8605Smrg r300->dsa_decompress_zmask); 487848b8605Smrg r300_blitter_end(r300); 488848b8605Smrg 489848b8605Smrg r300->zmask_decompress = FALSE; 490848b8605Smrg r300->zmask_in_use = FALSE; 491848b8605Smrg r300_mark_atom_dirty(r300, &r300->hyperz_state); 492848b8605Smrg} 493848b8605Smrg 494848b8605Smrgvoid r300_decompress_zmask_locked_unsafe(struct r300_context *r300) 495848b8605Smrg{ 496848b8605Smrg struct pipe_framebuffer_state fb; 497848b8605Smrg 498848b8605Smrg memset(&fb, 0, sizeof(fb)); 499848b8605Smrg fb.width = r300->locked_zbuffer->width; 500848b8605Smrg fb.height = r300->locked_zbuffer->height; 501848b8605Smrg fb.zsbuf = r300->locked_zbuffer; 502848b8605Smrg 503848b8605Smrg r300->context.set_framebuffer_state(&r300->context, &fb); 504848b8605Smrg r300_decompress_zmask(r300); 505848b8605Smrg} 506848b8605Smrg 507848b8605Smrgvoid r300_decompress_zmask_locked(struct r300_context *r300) 508848b8605Smrg{ 509848b8605Smrg struct pipe_framebuffer_state saved_fb; 510848b8605Smrg 511848b8605Smrg memset(&saved_fb, 0, sizeof(saved_fb)); 512848b8605Smrg util_copy_framebuffer_state(&saved_fb, r300->fb_state.state); 513848b8605Smrg r300_decompress_zmask_locked_unsafe(r300); 514848b8605Smrg r300->context.set_framebuffer_state(&r300->context, &saved_fb); 515848b8605Smrg util_unreference_framebuffer_state(&saved_fb); 516848b8605Smrg 517848b8605Smrg pipe_surface_reference(&r300->locked_zbuffer, NULL); 518848b8605Smrg} 519848b8605Smrg 520848b8605Smrgbool r300_is_blit_supported(enum pipe_format format) 521848b8605Smrg{ 522848b8605Smrg const struct util_format_description *desc = 523848b8605Smrg util_format_description(format); 524848b8605Smrg 525848b8605Smrg return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN || 526848b8605Smrg desc->layout == UTIL_FORMAT_LAYOUT_S3TC || 527848b8605Smrg desc->layout == UTIL_FORMAT_LAYOUT_RGTC; 528848b8605Smrg} 529848b8605Smrg 530848b8605Smrg/* Copy a block of pixels from one surface to another. */ 531848b8605Smrgstatic void r300_resource_copy_region(struct pipe_context *pipe, 532848b8605Smrg struct pipe_resource *dst, 533848b8605Smrg unsigned dst_level, 534848b8605Smrg unsigned dstx, unsigned dsty, unsigned dstz, 535848b8605Smrg struct pipe_resource *src, 536848b8605Smrg unsigned src_level, 537848b8605Smrg const struct pipe_box *src_box) 538848b8605Smrg{ 539848b8605Smrg struct pipe_screen *screen = pipe->screen; 540848b8605Smrg struct r300_context *r300 = r300_context(pipe); 541848b8605Smrg struct pipe_framebuffer_state *fb = 542848b8605Smrg (struct pipe_framebuffer_state*)r300->fb_state.state; 543848b8605Smrg unsigned src_width0 = r300_resource(src)->tex.width0; 544848b8605Smrg unsigned src_height0 = r300_resource(src)->tex.height0; 545848b8605Smrg unsigned dst_width0 = r300_resource(dst)->tex.width0; 546848b8605Smrg unsigned dst_height0 = r300_resource(dst)->tex.height0; 547848b8605Smrg unsigned layout; 548848b8605Smrg struct pipe_box box, dstbox; 549848b8605Smrg struct pipe_sampler_view src_templ, *src_view; 550848b8605Smrg struct pipe_surface dst_templ, *dst_view; 551848b8605Smrg 552848b8605Smrg /* Fallback for buffers. */ 553848b8605Smrg if ((dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) || 554848b8605Smrg !r300_is_blit_supported(dst->format)) { 555848b8605Smrg util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, 556848b8605Smrg src, src_level, src_box); 557848b8605Smrg return; 558848b8605Smrg } 559848b8605Smrg 560848b8605Smrg /* Can't read MSAA textures. */ 561848b8605Smrg if (src->nr_samples > 1 || dst->nr_samples > 1) { 562848b8605Smrg return; 563848b8605Smrg } 564848b8605Smrg 565848b8605Smrg /* The code below changes the texture format so that the copy can be done 566848b8605Smrg * on hardware. E.g. depth-stencil surfaces are copied as RGBA 567848b8605Smrg * colorbuffers. */ 568848b8605Smrg 569848b8605Smrg util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz); 570b8e80941Smrg util_blitter_default_src_texture(r300->blitter, &src_templ, src, src_level); 571848b8605Smrg 572848b8605Smrg layout = util_format_description(dst_templ.format)->layout; 573848b8605Smrg 574848b8605Smrg /* Handle non-renderable plain formats. */ 575848b8605Smrg if (layout == UTIL_FORMAT_LAYOUT_PLAIN && 576848b8605Smrg (!screen->is_format_supported(screen, src_templ.format, src->target, 577b8e80941Smrg src->nr_samples, src->nr_storage_samples, 578848b8605Smrg PIPE_BIND_SAMPLER_VIEW) || 579848b8605Smrg !screen->is_format_supported(screen, dst_templ.format, dst->target, 580b8e80941Smrg dst->nr_samples, dst->nr_storage_samples, 581848b8605Smrg PIPE_BIND_RENDER_TARGET))) { 582848b8605Smrg switch (util_format_get_blocksize(dst_templ.format)) { 583848b8605Smrg case 1: 584848b8605Smrg dst_templ.format = PIPE_FORMAT_I8_UNORM; 585848b8605Smrg break; 586848b8605Smrg case 2: 587848b8605Smrg dst_templ.format = PIPE_FORMAT_B4G4R4A4_UNORM; 588848b8605Smrg break; 589848b8605Smrg case 4: 590848b8605Smrg dst_templ.format = PIPE_FORMAT_B8G8R8A8_UNORM; 591848b8605Smrg break; 592848b8605Smrg case 8: 593848b8605Smrg dst_templ.format = PIPE_FORMAT_R16G16B16A16_UNORM; 594848b8605Smrg break; 595848b8605Smrg default: 596848b8605Smrg debug_printf("r300: copy_region: Unhandled format: %s. Falling back to software.\n" 597848b8605Smrg "r300: copy_region: Software fallback doesn't work for tiled textures.\n", 598848b8605Smrg util_format_short_name(dst_templ.format)); 599848b8605Smrg } 600848b8605Smrg src_templ.format = dst_templ.format; 601848b8605Smrg } 602848b8605Smrg 603848b8605Smrg /* Handle compressed formats. */ 604848b8605Smrg if (layout == UTIL_FORMAT_LAYOUT_S3TC || 605848b8605Smrg layout == UTIL_FORMAT_LAYOUT_RGTC) { 606848b8605Smrg assert(src_templ.format == dst_templ.format); 607848b8605Smrg 608848b8605Smrg box = *src_box; 609848b8605Smrg src_box = &box; 610848b8605Smrg 611848b8605Smrg dst_width0 = align(dst_width0, 4); 612848b8605Smrg dst_height0 = align(dst_height0, 4); 613848b8605Smrg src_width0 = align(src_width0, 4); 614848b8605Smrg src_height0 = align(src_height0, 4); 615848b8605Smrg box.width = align(box.width, 4); 616848b8605Smrg box.height = align(box.height, 4); 617848b8605Smrg 618848b8605Smrg switch (util_format_get_blocksize(dst_templ.format)) { 619848b8605Smrg case 8: 620848b8605Smrg /* one 4x4 pixel block has 8 bytes. 621848b8605Smrg * we set 1 pixel = 4 bytes ===> 1 block corrensponds to 2 pixels. */ 622848b8605Smrg dst_templ.format = PIPE_FORMAT_R8G8B8A8_UNORM; 623848b8605Smrg dst_width0 = dst_width0 / 2; 624848b8605Smrg src_width0 = src_width0 / 2; 625848b8605Smrg dstx /= 2; 626848b8605Smrg box.x /= 2; 627848b8605Smrg box.width /= 2; 628848b8605Smrg break; 629848b8605Smrg case 16: 630848b8605Smrg /* one 4x4 pixel block has 16 bytes. 631848b8605Smrg * we set 1 pixel = 4 bytes ===> 1 block corresponds to 4 pixels. */ 632848b8605Smrg dst_templ.format = PIPE_FORMAT_R8G8B8A8_UNORM; 633848b8605Smrg break; 634848b8605Smrg } 635848b8605Smrg src_templ.format = dst_templ.format; 636848b8605Smrg 637848b8605Smrg dst_height0 = dst_height0 / 4; 638848b8605Smrg src_height0 = src_height0 / 4; 639848b8605Smrg dsty /= 4; 640848b8605Smrg box.y /= 4; 641848b8605Smrg box.height /= 4; 642848b8605Smrg } 643848b8605Smrg 644848b8605Smrg /* Fallback for textures. */ 645848b8605Smrg if (!screen->is_format_supported(screen, dst_templ.format, 646848b8605Smrg dst->target, dst->nr_samples, 647b8e80941Smrg dst->nr_storage_samples, 648848b8605Smrg PIPE_BIND_RENDER_TARGET) || 649848b8605Smrg !screen->is_format_supported(screen, src_templ.format, 650848b8605Smrg src->target, src->nr_samples, 651b8e80941Smrg src->nr_storage_samples, 652848b8605Smrg PIPE_BIND_SAMPLER_VIEW)) { 653848b8605Smrg assert(0 && "this shouldn't happen, update r300_is_blit_supported"); 654848b8605Smrg util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, 655848b8605Smrg src, src_level, src_box); 656848b8605Smrg return; 657848b8605Smrg } 658848b8605Smrg 659848b8605Smrg /* Decompress ZMASK. */ 660848b8605Smrg if (r300->zmask_in_use && !r300->locked_zbuffer) { 661848b8605Smrg if (fb->zsbuf->texture == src || 662848b8605Smrg fb->zsbuf->texture == dst) { 663848b8605Smrg r300_decompress_zmask(r300); 664848b8605Smrg } 665848b8605Smrg } 666848b8605Smrg 667848b8605Smrg dst_view = r300_create_surface_custom(pipe, dst, &dst_templ, dst_width0, dst_height0); 668848b8605Smrg src_view = r300_create_sampler_view_custom(pipe, src, &src_templ, src_width0, src_height0); 669848b8605Smrg 670848b8605Smrg u_box_3d(dstx, dsty, dstz, abs(src_box->width), abs(src_box->height), 671848b8605Smrg abs(src_box->depth), &dstbox); 672848b8605Smrg 673848b8605Smrg r300_blitter_begin(r300, R300_COPY); 674848b8605Smrg util_blitter_blit_generic(r300->blitter, dst_view, &dstbox, 675848b8605Smrg src_view, src_box, src_width0, src_height0, 676b8e80941Smrg PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL, 677b8e80941Smrg FALSE); 678848b8605Smrg r300_blitter_end(r300); 679848b8605Smrg 680848b8605Smrg pipe_surface_reference(&dst_view, NULL); 681848b8605Smrg pipe_sampler_view_reference(&src_view, NULL); 682848b8605Smrg} 683848b8605Smrg 684848b8605Smrgstatic boolean r300_is_simple_msaa_resolve(const struct pipe_blit_info *info) 685848b8605Smrg{ 686848b8605Smrg unsigned dst_width = u_minify(info->dst.resource->width0, info->dst.level); 687848b8605Smrg unsigned dst_height = u_minify(info->dst.resource->height0, info->dst.level); 688848b8605Smrg 689b8e80941Smrg return info->src.resource->nr_samples > 1 && 690b8e80941Smrg info->dst.resource->nr_samples <= 1 && 691b8e80941Smrg info->dst.resource->format == info->src.resource->format && 692848b8605Smrg info->dst.resource->format == info->dst.format && 693848b8605Smrg info->src.resource->format == info->src.format && 694848b8605Smrg !info->scissor_enable && 695848b8605Smrg info->mask == PIPE_MASK_RGBA && 696848b8605Smrg dst_width == info->src.resource->width0 && 697848b8605Smrg dst_height == info->src.resource->height0 && 698848b8605Smrg info->dst.box.x == 0 && 699848b8605Smrg info->dst.box.y == 0 && 700848b8605Smrg info->dst.box.width == dst_width && 701848b8605Smrg info->dst.box.height == dst_height && 702848b8605Smrg info->src.box.x == 0 && 703848b8605Smrg info->src.box.y == 0 && 704848b8605Smrg info->src.box.width == dst_width && 705848b8605Smrg info->src.box.height == dst_height && 706848b8605Smrg (r300_resource(info->dst.resource)->tex.microtile != RADEON_LAYOUT_LINEAR || 707848b8605Smrg r300_resource(info->dst.resource)->tex.macrotile[info->dst.level] != RADEON_LAYOUT_LINEAR); 708848b8605Smrg} 709848b8605Smrg 710848b8605Smrgstatic void r300_simple_msaa_resolve(struct pipe_context *pipe, 711848b8605Smrg struct pipe_resource *dst, 712848b8605Smrg unsigned dst_level, 713848b8605Smrg unsigned dst_layer, 714848b8605Smrg struct pipe_resource *src, 715848b8605Smrg enum pipe_format format) 716848b8605Smrg{ 717848b8605Smrg struct r300_context *r300 = r300_context(pipe); 718848b8605Smrg struct r300_surface *srcsurf, *dstsurf; 719848b8605Smrg struct pipe_surface surf_tmpl; 720848b8605Smrg struct r300_aa_state *aa = (struct r300_aa_state*)r300->aa_state.state; 721848b8605Smrg 722848b8605Smrg memset(&surf_tmpl, 0, sizeof(surf_tmpl)); 723848b8605Smrg surf_tmpl.format = format; 724848b8605Smrg srcsurf = r300_surface(pipe->create_surface(pipe, src, &surf_tmpl)); 725848b8605Smrg 726848b8605Smrg surf_tmpl.format = format; 727848b8605Smrg surf_tmpl.u.tex.level = dst_level; 728848b8605Smrg surf_tmpl.u.tex.first_layer = 729848b8605Smrg surf_tmpl.u.tex.last_layer = dst_layer; 730848b8605Smrg dstsurf = r300_surface(pipe->create_surface(pipe, dst, &surf_tmpl)); 731848b8605Smrg 732848b8605Smrg /* COLORPITCH should contain the tiling info of the resolve buffer. 733848b8605Smrg * The tiling of the AA buffer isn't programmable anyway. */ 734848b8605Smrg srcsurf->pitch &= ~(R300_COLOR_TILE(1) | R300_COLOR_MICROTILE(3)); 735848b8605Smrg srcsurf->pitch |= dstsurf->pitch & (R300_COLOR_TILE(1) | R300_COLOR_MICROTILE(3)); 736848b8605Smrg 737848b8605Smrg /* Enable AA resolve. */ 738848b8605Smrg aa->dest = dstsurf; 739848b8605Smrg r300->aa_state.size = 8; 740848b8605Smrg r300_mark_atom_dirty(r300, &r300->aa_state); 741848b8605Smrg 742848b8605Smrg /* Resolve the surface. */ 743848b8605Smrg r300_blitter_begin(r300, R300_CLEAR_SURFACE); 744848b8605Smrg util_blitter_custom_color(r300->blitter, &srcsurf->base, NULL); 745848b8605Smrg r300_blitter_end(r300); 746848b8605Smrg 747848b8605Smrg /* Disable AA resolve. */ 748848b8605Smrg aa->dest = NULL; 749848b8605Smrg r300->aa_state.size = 4; 750848b8605Smrg r300_mark_atom_dirty(r300, &r300->aa_state); 751848b8605Smrg 752848b8605Smrg pipe_surface_reference((struct pipe_surface**)&srcsurf, NULL); 753848b8605Smrg pipe_surface_reference((struct pipe_surface**)&dstsurf, NULL); 754848b8605Smrg} 755848b8605Smrg 756848b8605Smrgstatic void r300_msaa_resolve(struct pipe_context *pipe, 757848b8605Smrg const struct pipe_blit_info *info) 758848b8605Smrg{ 759848b8605Smrg struct r300_context *r300 = r300_context(pipe); 760848b8605Smrg struct pipe_screen *screen = pipe->screen; 761848b8605Smrg struct pipe_resource *tmp, templ; 762848b8605Smrg struct pipe_blit_info blit; 763848b8605Smrg 764848b8605Smrg assert(info->src.level == 0); 765848b8605Smrg assert(info->src.box.z == 0); 766848b8605Smrg assert(info->src.box.depth == 1); 767848b8605Smrg assert(info->dst.box.depth == 1); 768848b8605Smrg 769848b8605Smrg if (r300_is_simple_msaa_resolve(info)) { 770848b8605Smrg r300_simple_msaa_resolve(pipe, info->dst.resource, info->dst.level, 771848b8605Smrg info->dst.box.z, info->src.resource, 772848b8605Smrg info->src.format); 773848b8605Smrg return; 774848b8605Smrg } 775848b8605Smrg 776848b8605Smrg /* resolve into a temporary texture, then blit */ 777848b8605Smrg memset(&templ, 0, sizeof(templ)); 778848b8605Smrg templ.target = PIPE_TEXTURE_2D; 779848b8605Smrg templ.format = info->src.resource->format; 780848b8605Smrg templ.width0 = info->src.resource->width0; 781848b8605Smrg templ.height0 = info->src.resource->height0; 782848b8605Smrg templ.depth0 = 1; 783848b8605Smrg templ.array_size = 1; 784848b8605Smrg templ.usage = PIPE_USAGE_DEFAULT; 785848b8605Smrg templ.flags = R300_RESOURCE_FORCE_MICROTILING; 786848b8605Smrg 787848b8605Smrg tmp = screen->resource_create(screen, &templ); 788848b8605Smrg 789848b8605Smrg /* resolve */ 790848b8605Smrg r300_simple_msaa_resolve(pipe, tmp, 0, 0, info->src.resource, 791848b8605Smrg info->src.format); 792848b8605Smrg 793848b8605Smrg /* blit */ 794848b8605Smrg blit = *info; 795848b8605Smrg blit.src.resource = tmp; 796848b8605Smrg blit.src.box.z = 0; 797848b8605Smrg 798848b8605Smrg r300_blitter_begin(r300, R300_BLIT | R300_IGNORE_RENDER_COND); 799848b8605Smrg util_blitter_blit(r300->blitter, &blit); 800848b8605Smrg r300_blitter_end(r300); 801848b8605Smrg 802848b8605Smrg pipe_resource_reference(&tmp, NULL); 803848b8605Smrg} 804848b8605Smrg 805848b8605Smrgstatic void r300_blit(struct pipe_context *pipe, 806848b8605Smrg const struct pipe_blit_info *blit) 807848b8605Smrg{ 808848b8605Smrg struct r300_context *r300 = r300_context(pipe); 809848b8605Smrg struct pipe_framebuffer_state *fb = 810848b8605Smrg (struct pipe_framebuffer_state*)r300->fb_state.state; 811848b8605Smrg struct pipe_blit_info info = *blit; 812848b8605Smrg 813b8e80941Smrg /* The driver supports sRGB textures but not framebuffers. Blitting 814b8e80941Smrg * from sRGB to sRGB should be the same as blitting from linear 815b8e80941Smrg * to linear, so use that, This avoids incorrect linearization. 816b8e80941Smrg */ 817b8e80941Smrg if (util_format_is_srgb(info.src.format)) { 818b8e80941Smrg info.src.format = util_format_linear(info.src.format); 819b8e80941Smrg info.dst.format = util_format_linear(info.dst.format); 820b8e80941Smrg } 821b8e80941Smrg 822848b8605Smrg /* MSAA resolve. */ 823848b8605Smrg if (info.src.resource->nr_samples > 1 && 824848b8605Smrg !util_format_is_depth_or_stencil(info.src.resource->format)) { 825848b8605Smrg r300_msaa_resolve(pipe, &info); 826848b8605Smrg return; 827848b8605Smrg } 828848b8605Smrg 829848b8605Smrg /* Can't read MSAA textures. */ 830848b8605Smrg if (info.src.resource->nr_samples > 1) { 831848b8605Smrg return; 832848b8605Smrg } 833848b8605Smrg 834848b8605Smrg /* Blit a combined depth-stencil resource as color. 835848b8605Smrg * S8Z24 is the only supported stencil format. */ 836848b8605Smrg if ((info.mask & PIPE_MASK_S) && 837848b8605Smrg info.src.format == PIPE_FORMAT_S8_UINT_Z24_UNORM && 838848b8605Smrg info.dst.format == PIPE_FORMAT_S8_UINT_Z24_UNORM) { 839848b8605Smrg if (info.dst.resource->nr_samples > 1) { 840848b8605Smrg /* Cannot do that with MSAA buffers. */ 841848b8605Smrg info.mask &= ~PIPE_MASK_S; 842848b8605Smrg if (!(info.mask & PIPE_MASK_Z)) { 843848b8605Smrg return; 844848b8605Smrg } 845848b8605Smrg } else { 846848b8605Smrg /* Single-sample buffer. */ 847848b8605Smrg info.src.format = PIPE_FORMAT_B8G8R8A8_UNORM; 848848b8605Smrg info.dst.format = PIPE_FORMAT_B8G8R8A8_UNORM; 849848b8605Smrg if (info.mask & PIPE_MASK_Z) { 850848b8605Smrg info.mask = PIPE_MASK_RGBA; /* depth+stencil */ 851848b8605Smrg } else { 852848b8605Smrg info.mask = PIPE_MASK_B; /* stencil only */ 853848b8605Smrg } 854848b8605Smrg } 855848b8605Smrg } 856848b8605Smrg 857848b8605Smrg /* Decompress ZMASK. */ 858848b8605Smrg if (r300->zmask_in_use && !r300->locked_zbuffer) { 859848b8605Smrg if (fb->zsbuf->texture == info.src.resource || 860848b8605Smrg fb->zsbuf->texture == info.dst.resource) { 861848b8605Smrg r300_decompress_zmask(r300); 862848b8605Smrg } 863848b8605Smrg } 864848b8605Smrg 865848b8605Smrg r300_blitter_begin(r300, R300_BLIT | 866848b8605Smrg (info.render_condition_enable ? 0 : R300_IGNORE_RENDER_COND)); 867848b8605Smrg util_blitter_blit(r300->blitter, &info); 868848b8605Smrg r300_blitter_end(r300); 869848b8605Smrg} 870848b8605Smrg 871848b8605Smrgstatic void r300_flush_resource(struct pipe_context *ctx, 872848b8605Smrg struct pipe_resource *resource) 873848b8605Smrg{ 874848b8605Smrg} 875848b8605Smrg 876848b8605Smrgvoid r300_init_blit_functions(struct r300_context *r300) 877848b8605Smrg{ 878848b8605Smrg r300->context.clear = r300_clear; 879848b8605Smrg r300->context.clear_render_target = r300_clear_render_target; 880848b8605Smrg r300->context.clear_depth_stencil = r300_clear_depth_stencil; 881848b8605Smrg r300->context.resource_copy_region = r300_resource_copy_region; 882848b8605Smrg r300->context.blit = r300_blit; 883848b8605Smrg r300->context.flush_resource = r300_flush_resource; 884848b8605Smrg} 885