1848b8605Smrg/* 2848b8605Smrg * Copyright 2010 Jerome Glisse <glisse@freedesktop.org> 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 "r600_pipe.h" 24b8e80941Smrg#include "compute_memory_pool.h" 25b8e80941Smrg#include "evergreen_compute.h" 26848b8605Smrg#include "util/u_surface.h" 27848b8605Smrg#include "util/u_format.h" 28848b8605Smrg#include "evergreend.h" 29848b8605Smrg 30848b8605Smrgenum r600_blitter_op /* bitmask */ 31848b8605Smrg{ 32848b8605Smrg R600_SAVE_FRAGMENT_STATE = 1, 33848b8605Smrg R600_SAVE_TEXTURES = 2, 34848b8605Smrg R600_SAVE_FRAMEBUFFER = 4, 35848b8605Smrg R600_DISABLE_RENDER_COND = 8, 36848b8605Smrg 37848b8605Smrg R600_CLEAR = R600_SAVE_FRAGMENT_STATE, 38848b8605Smrg 39848b8605Smrg R600_CLEAR_SURFACE = R600_SAVE_FRAGMENT_STATE | R600_SAVE_FRAMEBUFFER, 40848b8605Smrg 41848b8605Smrg R600_COPY_BUFFER = R600_DISABLE_RENDER_COND, 42848b8605Smrg 43848b8605Smrg R600_COPY_TEXTURE = R600_SAVE_FRAGMENT_STATE | R600_SAVE_FRAMEBUFFER | R600_SAVE_TEXTURES | 44848b8605Smrg R600_DISABLE_RENDER_COND, 45848b8605Smrg 46848b8605Smrg R600_BLIT = R600_SAVE_FRAGMENT_STATE | R600_SAVE_FRAMEBUFFER | R600_SAVE_TEXTURES, 47848b8605Smrg 48848b8605Smrg R600_DECOMPRESS = R600_SAVE_FRAGMENT_STATE | R600_SAVE_FRAMEBUFFER | R600_DISABLE_RENDER_COND, 49848b8605Smrg 50848b8605Smrg R600_COLOR_RESOLVE = R600_SAVE_FRAGMENT_STATE | R600_SAVE_FRAMEBUFFER 51848b8605Smrg}; 52848b8605Smrg 53848b8605Smrgstatic void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op) 54848b8605Smrg{ 55848b8605Smrg struct r600_context *rctx = (struct r600_context *)ctx; 56848b8605Smrg 57b8e80941Smrg if (rctx->cmd_buf_is_compute) { 58b8e80941Smrg rctx->b.gfx.flush(rctx, PIPE_FLUSH_ASYNC, NULL); 59b8e80941Smrg rctx->cmd_buf_is_compute = false; 60b8e80941Smrg } 61848b8605Smrg 62848b8605Smrg util_blitter_save_vertex_buffer_slot(rctx->blitter, rctx->vertex_buffer_state.vb); 63848b8605Smrg util_blitter_save_vertex_elements(rctx->blitter, rctx->vertex_fetch_shader.cso); 64848b8605Smrg util_blitter_save_vertex_shader(rctx->blitter, rctx->vs_shader); 65848b8605Smrg util_blitter_save_geometry_shader(rctx->blitter, rctx->gs_shader); 66b8e80941Smrg util_blitter_save_tessctrl_shader(rctx->blitter, rctx->tcs_shader); 67b8e80941Smrg util_blitter_save_tesseval_shader(rctx->blitter, rctx->tes_shader); 68848b8605Smrg util_blitter_save_so_targets(rctx->blitter, rctx->b.streamout.num_targets, 69848b8605Smrg (struct pipe_stream_output_target**)rctx->b.streamout.targets); 70848b8605Smrg util_blitter_save_rasterizer(rctx->blitter, rctx->rasterizer_state.cso); 71848b8605Smrg 72848b8605Smrg if (op & R600_SAVE_FRAGMENT_STATE) { 73b8e80941Smrg util_blitter_save_viewport(rctx->blitter, &rctx->b.viewports.states[0]); 74b8e80941Smrg util_blitter_save_scissor(rctx->blitter, &rctx->b.scissors.states[0]); 75848b8605Smrg util_blitter_save_fragment_shader(rctx->blitter, rctx->ps_shader); 76848b8605Smrg util_blitter_save_blend(rctx->blitter, rctx->blend_state.cso); 77848b8605Smrg util_blitter_save_depth_stencil_alpha(rctx->blitter, rctx->dsa_state.cso); 78848b8605Smrg util_blitter_save_stencil_ref(rctx->blitter, &rctx->stencil_ref.pipe_state); 79848b8605Smrg util_blitter_save_sample_mask(rctx->blitter, rctx->sample_mask.sample_mask); 80848b8605Smrg } 81848b8605Smrg 82848b8605Smrg if (op & R600_SAVE_FRAMEBUFFER) 83848b8605Smrg util_blitter_save_framebuffer(rctx->blitter, &rctx->framebuffer.state); 84848b8605Smrg 85848b8605Smrg if (op & R600_SAVE_TEXTURES) { 86848b8605Smrg util_blitter_save_fragment_sampler_states( 87848b8605Smrg rctx->blitter, util_last_bit(rctx->samplers[PIPE_SHADER_FRAGMENT].states.enabled_mask), 88848b8605Smrg (void**)rctx->samplers[PIPE_SHADER_FRAGMENT].states.states); 89848b8605Smrg 90848b8605Smrg util_blitter_save_fragment_sampler_views( 91848b8605Smrg rctx->blitter, util_last_bit(rctx->samplers[PIPE_SHADER_FRAGMENT].views.enabled_mask), 92848b8605Smrg (struct pipe_sampler_view**)rctx->samplers[PIPE_SHADER_FRAGMENT].views.views); 93848b8605Smrg } 94848b8605Smrg 95b8e80941Smrg if (op & R600_DISABLE_RENDER_COND) 96b8e80941Smrg rctx->b.render_cond_force_off = true; 97848b8605Smrg} 98848b8605Smrg 99848b8605Smrgstatic void r600_blitter_end(struct pipe_context *ctx) 100848b8605Smrg{ 101848b8605Smrg struct r600_context *rctx = (struct r600_context *)ctx; 102b8e80941Smrg 103b8e80941Smrg rctx->b.render_cond_force_off = false; 104848b8605Smrg} 105848b8605Smrg 106848b8605Smrgstatic unsigned u_max_sample(struct pipe_resource *r) 107848b8605Smrg{ 108848b8605Smrg return r->nr_samples ? r->nr_samples - 1 : 0; 109848b8605Smrg} 110848b8605Smrg 111848b8605Smrgstatic void r600_blit_decompress_depth(struct pipe_context *ctx, 112848b8605Smrg struct r600_texture *texture, 113848b8605Smrg struct r600_texture *staging, 114848b8605Smrg unsigned first_level, unsigned last_level, 115848b8605Smrg unsigned first_layer, unsigned last_layer, 116848b8605Smrg unsigned first_sample, unsigned last_sample) 117848b8605Smrg{ 118848b8605Smrg struct r600_context *rctx = (struct r600_context *)ctx; 119848b8605Smrg unsigned layer, level, sample, checked_last_layer, max_layer, max_sample; 120848b8605Smrg struct r600_texture *flushed_depth_texture = staging ? 121848b8605Smrg staging : texture->flushed_depth_texture; 122848b8605Smrg const struct util_format_description *desc = 123848b8605Smrg util_format_description(texture->resource.b.b.format); 124848b8605Smrg float depth; 125848b8605Smrg 126848b8605Smrg if (!staging && !texture->dirty_level_mask) 127848b8605Smrg return; 128848b8605Smrg 129848b8605Smrg max_sample = u_max_sample(&texture->resource.b.b); 130848b8605Smrg 131848b8605Smrg /* XXX Decompressing MSAA depth textures is broken on R6xx. 132848b8605Smrg * There is also a hardlock if CMASK and FMASK are not present. 133848b8605Smrg * Just skip this until we find out how to fix it. */ 134848b8605Smrg if (rctx->b.chip_class == R600 && max_sample > 0) { 135848b8605Smrg texture->dirty_level_mask = 0; 136848b8605Smrg return; 137848b8605Smrg } 138848b8605Smrg 139848b8605Smrg if (rctx->b.family == CHIP_RV610 || rctx->b.family == CHIP_RV630 || 140848b8605Smrg rctx->b.family == CHIP_RV620 || rctx->b.family == CHIP_RV635) 141848b8605Smrg depth = 0.0f; 142848b8605Smrg else 143848b8605Smrg depth = 1.0f; 144848b8605Smrg 145848b8605Smrg /* Enable decompression in DB_RENDER_CONTROL */ 146848b8605Smrg rctx->db_misc_state.flush_depthstencil_through_cb = true; 147848b8605Smrg rctx->db_misc_state.copy_depth = util_format_has_depth(desc); 148848b8605Smrg rctx->db_misc_state.copy_stencil = util_format_has_stencil(desc); 149848b8605Smrg rctx->db_misc_state.copy_sample = first_sample; 150b8e80941Smrg r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom); 151848b8605Smrg 152848b8605Smrg for (level = first_level; level <= last_level; level++) { 153848b8605Smrg if (!staging && !(texture->dirty_level_mask & (1 << level))) 154848b8605Smrg continue; 155848b8605Smrg 156848b8605Smrg /* The smaller the mipmap level, the less layers there are 157848b8605Smrg * as far as 3D textures are concerned. */ 158848b8605Smrg max_layer = util_max_layer(&texture->resource.b.b, level); 159848b8605Smrg checked_last_layer = last_layer < max_layer ? last_layer : max_layer; 160848b8605Smrg 161848b8605Smrg for (layer = first_layer; layer <= checked_last_layer; layer++) { 162848b8605Smrg for (sample = first_sample; sample <= last_sample; sample++) { 163848b8605Smrg struct pipe_surface *zsurf, *cbsurf, surf_tmpl; 164848b8605Smrg 165848b8605Smrg if (sample != rctx->db_misc_state.copy_sample) { 166848b8605Smrg rctx->db_misc_state.copy_sample = sample; 167b8e80941Smrg r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom); 168848b8605Smrg } 169848b8605Smrg 170848b8605Smrg surf_tmpl.format = texture->resource.b.b.format; 171848b8605Smrg surf_tmpl.u.tex.level = level; 172848b8605Smrg surf_tmpl.u.tex.first_layer = layer; 173848b8605Smrg surf_tmpl.u.tex.last_layer = layer; 174848b8605Smrg 175848b8605Smrg zsurf = ctx->create_surface(ctx, &texture->resource.b.b, &surf_tmpl); 176848b8605Smrg 177848b8605Smrg surf_tmpl.format = flushed_depth_texture->resource.b.b.format; 178848b8605Smrg cbsurf = ctx->create_surface(ctx, 179848b8605Smrg &flushed_depth_texture->resource.b.b, &surf_tmpl); 180848b8605Smrg 181848b8605Smrg r600_blitter_begin(ctx, R600_DECOMPRESS); 182848b8605Smrg util_blitter_custom_depth_stencil(rctx->blitter, zsurf, cbsurf, 1 << sample, 183848b8605Smrg rctx->custom_dsa_flush, depth); 184848b8605Smrg r600_blitter_end(ctx); 185848b8605Smrg 186848b8605Smrg pipe_surface_reference(&zsurf, NULL); 187848b8605Smrg pipe_surface_reference(&cbsurf, NULL); 188848b8605Smrg } 189848b8605Smrg } 190848b8605Smrg 191848b8605Smrg /* The texture will always be dirty if some layers or samples aren't flushed. 192848b8605Smrg * I don't think this case occurs often though. */ 193848b8605Smrg if (!staging && 194848b8605Smrg first_layer == 0 && last_layer == max_layer && 195848b8605Smrg first_sample == 0 && last_sample == max_sample) { 196848b8605Smrg texture->dirty_level_mask &= ~(1 << level); 197848b8605Smrg } 198848b8605Smrg } 199848b8605Smrg 200848b8605Smrg /* reenable compression in DB_RENDER_CONTROL */ 201848b8605Smrg rctx->db_misc_state.flush_depthstencil_through_cb = false; 202b8e80941Smrg r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom); 203848b8605Smrg} 204848b8605Smrg 205848b8605Smrgstatic void r600_blit_decompress_depth_in_place(struct r600_context *rctx, 206848b8605Smrg struct r600_texture *texture, 207b8e80941Smrg bool is_stencil_sampler, 208848b8605Smrg unsigned first_level, unsigned last_level, 209848b8605Smrg unsigned first_layer, unsigned last_layer) 210848b8605Smrg{ 211848b8605Smrg struct pipe_surface *zsurf, surf_tmpl = {{0}}; 212848b8605Smrg unsigned layer, max_layer, checked_last_layer, level; 213b8e80941Smrg unsigned *dirty_level_mask; 214848b8605Smrg 215848b8605Smrg /* Enable decompression in DB_RENDER_CONTROL */ 216b8e80941Smrg if (is_stencil_sampler) { 217b8e80941Smrg rctx->db_misc_state.flush_stencil_inplace = true; 218b8e80941Smrg dirty_level_mask = &texture->stencil_dirty_level_mask; 219b8e80941Smrg } else { 220b8e80941Smrg rctx->db_misc_state.flush_depth_inplace = true; 221b8e80941Smrg dirty_level_mask = &texture->dirty_level_mask; 222b8e80941Smrg } 223b8e80941Smrg r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom); 224848b8605Smrg 225848b8605Smrg surf_tmpl.format = texture->resource.b.b.format; 226848b8605Smrg 227848b8605Smrg for (level = first_level; level <= last_level; level++) { 228b8e80941Smrg if (!(*dirty_level_mask & (1 << level))) 229848b8605Smrg continue; 230848b8605Smrg 231848b8605Smrg surf_tmpl.u.tex.level = level; 232848b8605Smrg 233848b8605Smrg /* The smaller the mipmap level, the less layers there are 234848b8605Smrg * as far as 3D textures are concerned. */ 235848b8605Smrg max_layer = util_max_layer(&texture->resource.b.b, level); 236848b8605Smrg checked_last_layer = last_layer < max_layer ? last_layer : max_layer; 237848b8605Smrg 238848b8605Smrg for (layer = first_layer; layer <= checked_last_layer; layer++) { 239848b8605Smrg surf_tmpl.u.tex.first_layer = layer; 240848b8605Smrg surf_tmpl.u.tex.last_layer = layer; 241848b8605Smrg 242848b8605Smrg zsurf = rctx->b.b.create_surface(&rctx->b.b, &texture->resource.b.b, &surf_tmpl); 243848b8605Smrg 244848b8605Smrg r600_blitter_begin(&rctx->b.b, R600_DECOMPRESS); 245848b8605Smrg util_blitter_custom_depth_stencil(rctx->blitter, zsurf, NULL, ~0, 246848b8605Smrg rctx->custom_dsa_flush, 1.0f); 247848b8605Smrg r600_blitter_end(&rctx->b.b); 248848b8605Smrg 249848b8605Smrg pipe_surface_reference(&zsurf, NULL); 250848b8605Smrg } 251848b8605Smrg 252848b8605Smrg /* The texture will always be dirty if some layers or samples aren't flushed. 253848b8605Smrg * I don't think this case occurs often though. */ 254848b8605Smrg if (first_layer == 0 && last_layer == max_layer) { 255b8e80941Smrg *dirty_level_mask &= ~(1 << level); 256848b8605Smrg } 257848b8605Smrg } 258848b8605Smrg 259848b8605Smrg /* Disable decompression in DB_RENDER_CONTROL */ 260b8e80941Smrg rctx->db_misc_state.flush_depth_inplace = false; 261b8e80941Smrg rctx->db_misc_state.flush_stencil_inplace = false; 262b8e80941Smrg r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom); 263848b8605Smrg} 264848b8605Smrg 265848b8605Smrgvoid r600_decompress_depth_textures(struct r600_context *rctx, 266848b8605Smrg struct r600_samplerview_state *textures) 267848b8605Smrg{ 268848b8605Smrg unsigned i; 269848b8605Smrg unsigned depth_texture_mask = textures->compressed_depthtex_mask; 270848b8605Smrg 271848b8605Smrg while (depth_texture_mask) { 272848b8605Smrg struct pipe_sampler_view *view; 273b8e80941Smrg struct r600_pipe_sampler_view *rview; 274848b8605Smrg struct r600_texture *tex; 275848b8605Smrg 276848b8605Smrg i = u_bit_scan(&depth_texture_mask); 277848b8605Smrg 278848b8605Smrg view = &textures->views[i]->base; 279848b8605Smrg assert(view); 280b8e80941Smrg rview = (struct r600_pipe_sampler_view*)view; 281848b8605Smrg 282848b8605Smrg tex = (struct r600_texture *)view->texture; 283b8e80941Smrg assert(tex->db_compatible); 284848b8605Smrg 285b8e80941Smrg if (r600_can_sample_zs(tex, rview->is_stencil_sampler)) { 286848b8605Smrg r600_blit_decompress_depth_in_place(rctx, tex, 287b8e80941Smrg rview->is_stencil_sampler, 288848b8605Smrg view->u.tex.first_level, view->u.tex.last_level, 289848b8605Smrg 0, util_max_layer(&tex->resource.b.b, view->u.tex.first_level)); 290848b8605Smrg } else { 291848b8605Smrg r600_blit_decompress_depth(&rctx->b.b, tex, NULL, 292848b8605Smrg view->u.tex.first_level, view->u.tex.last_level, 293848b8605Smrg 0, util_max_layer(&tex->resource.b.b, view->u.tex.first_level), 294848b8605Smrg 0, u_max_sample(&tex->resource.b.b)); 295848b8605Smrg } 296848b8605Smrg } 297848b8605Smrg} 298848b8605Smrg 299b8e80941Smrgvoid r600_decompress_depth_images(struct r600_context *rctx, 300b8e80941Smrg struct r600_image_state *images) 301b8e80941Smrg{ 302b8e80941Smrg unsigned i; 303b8e80941Smrg unsigned depth_texture_mask = images->compressed_depthtex_mask; 304b8e80941Smrg 305b8e80941Smrg while (depth_texture_mask) { 306b8e80941Smrg struct r600_image_view *view; 307b8e80941Smrg struct r600_texture *tex; 308b8e80941Smrg 309b8e80941Smrg i = u_bit_scan(&depth_texture_mask); 310b8e80941Smrg 311b8e80941Smrg view = &images->views[i]; 312b8e80941Smrg assert(view); 313b8e80941Smrg 314b8e80941Smrg tex = (struct r600_texture *)view->base.resource; 315b8e80941Smrg assert(tex->db_compatible); 316b8e80941Smrg 317b8e80941Smrg if (r600_can_sample_zs(tex, false)) { 318b8e80941Smrg r600_blit_decompress_depth_in_place(rctx, tex, 319b8e80941Smrg false, 320b8e80941Smrg view->base.u.tex.level, 321b8e80941Smrg view->base.u.tex.level, 322b8e80941Smrg 0, util_max_layer(&tex->resource.b.b, view->base.u.tex.level)); 323b8e80941Smrg } else { 324b8e80941Smrg r600_blit_decompress_depth(&rctx->b.b, tex, NULL, 325b8e80941Smrg view->base.u.tex.level, 326b8e80941Smrg view->base.u.tex.level, 327b8e80941Smrg 0, util_max_layer(&tex->resource.b.b, view->base.u.tex.level), 328b8e80941Smrg 0, u_max_sample(&tex->resource.b.b)); 329b8e80941Smrg } 330b8e80941Smrg } 331b8e80941Smrg} 332b8e80941Smrg 333848b8605Smrgstatic void r600_blit_decompress_color(struct pipe_context *ctx, 334848b8605Smrg struct r600_texture *rtex, 335848b8605Smrg unsigned first_level, unsigned last_level, 336848b8605Smrg unsigned first_layer, unsigned last_layer) 337848b8605Smrg{ 338848b8605Smrg struct r600_context *rctx = (struct r600_context *)ctx; 339848b8605Smrg unsigned layer, level, checked_last_layer, max_layer; 340848b8605Smrg 341848b8605Smrg if (!rtex->dirty_level_mask) 342848b8605Smrg return; 343848b8605Smrg 344848b8605Smrg for (level = first_level; level <= last_level; level++) { 345848b8605Smrg if (!(rtex->dirty_level_mask & (1 << level))) 346848b8605Smrg continue; 347848b8605Smrg 348848b8605Smrg /* The smaller the mipmap level, the less layers there are 349848b8605Smrg * as far as 3D textures are concerned. */ 350848b8605Smrg max_layer = util_max_layer(&rtex->resource.b.b, level); 351848b8605Smrg checked_last_layer = last_layer < max_layer ? last_layer : max_layer; 352848b8605Smrg 353848b8605Smrg for (layer = first_layer; layer <= checked_last_layer; layer++) { 354848b8605Smrg struct pipe_surface *cbsurf, surf_tmpl; 355848b8605Smrg 356848b8605Smrg surf_tmpl.format = rtex->resource.b.b.format; 357848b8605Smrg surf_tmpl.u.tex.level = level; 358848b8605Smrg surf_tmpl.u.tex.first_layer = layer; 359848b8605Smrg surf_tmpl.u.tex.last_layer = layer; 360848b8605Smrg cbsurf = ctx->create_surface(ctx, &rtex->resource.b.b, &surf_tmpl); 361848b8605Smrg 362848b8605Smrg r600_blitter_begin(ctx, R600_DECOMPRESS); 363848b8605Smrg util_blitter_custom_color(rctx->blitter, cbsurf, 364848b8605Smrg rtex->fmask.size ? rctx->custom_blend_decompress : rctx->custom_blend_fastclear); 365848b8605Smrg r600_blitter_end(ctx); 366848b8605Smrg 367848b8605Smrg pipe_surface_reference(&cbsurf, NULL); 368848b8605Smrg } 369848b8605Smrg 370848b8605Smrg /* The texture will always be dirty if some layers aren't flushed. 371848b8605Smrg * I don't think this case occurs often though. */ 372848b8605Smrg if (first_layer == 0 && last_layer == max_layer) { 373848b8605Smrg rtex->dirty_level_mask &= ~(1 << level); 374848b8605Smrg } 375848b8605Smrg } 376848b8605Smrg} 377848b8605Smrg 378848b8605Smrgvoid r600_decompress_color_textures(struct r600_context *rctx, 379848b8605Smrg struct r600_samplerview_state *textures) 380848b8605Smrg{ 381848b8605Smrg unsigned i; 382848b8605Smrg unsigned mask = textures->compressed_colortex_mask; 383848b8605Smrg 384848b8605Smrg while (mask) { 385848b8605Smrg struct pipe_sampler_view *view; 386848b8605Smrg struct r600_texture *tex; 387848b8605Smrg 388848b8605Smrg i = u_bit_scan(&mask); 389848b8605Smrg 390848b8605Smrg view = &textures->views[i]->base; 391848b8605Smrg assert(view); 392848b8605Smrg 393848b8605Smrg tex = (struct r600_texture *)view->texture; 394848b8605Smrg assert(tex->cmask.size); 395848b8605Smrg 396848b8605Smrg r600_blit_decompress_color(&rctx->b.b, tex, 397848b8605Smrg view->u.tex.first_level, view->u.tex.last_level, 398848b8605Smrg 0, util_max_layer(&tex->resource.b.b, view->u.tex.first_level)); 399848b8605Smrg } 400848b8605Smrg} 401848b8605Smrg 402b8e80941Smrgvoid r600_decompress_color_images(struct r600_context *rctx, 403b8e80941Smrg struct r600_image_state *images) 404b8e80941Smrg{ 405b8e80941Smrg unsigned i; 406b8e80941Smrg unsigned mask = images->compressed_colortex_mask; 407b8e80941Smrg 408b8e80941Smrg while (mask) { 409b8e80941Smrg struct r600_image_view *view; 410b8e80941Smrg struct r600_texture *tex; 411b8e80941Smrg 412b8e80941Smrg i = u_bit_scan(&mask); 413b8e80941Smrg 414b8e80941Smrg view = &images->views[i]; 415b8e80941Smrg assert(view); 416b8e80941Smrg 417b8e80941Smrg tex = (struct r600_texture *)view->base.resource; 418b8e80941Smrg assert(tex->cmask.size); 419b8e80941Smrg 420b8e80941Smrg r600_blit_decompress_color(&rctx->b.b, tex, 421b8e80941Smrg view->base.u.tex.level, view->base.u.tex.level, 422b8e80941Smrg view->base.u.tex.first_layer, 423b8e80941Smrg view->base.u.tex.last_layer); 424b8e80941Smrg } 425b8e80941Smrg} 426b8e80941Smrg 427848b8605Smrg/* Helper for decompressing a portion of a color or depth resource before 428848b8605Smrg * blitting if any decompression is needed. 429848b8605Smrg * The driver doesn't decompress resources automatically while u_blitter is 430848b8605Smrg * rendering. */ 431848b8605Smrgstatic bool r600_decompress_subresource(struct pipe_context *ctx, 432848b8605Smrg struct pipe_resource *tex, 433848b8605Smrg unsigned level, 434848b8605Smrg unsigned first_layer, unsigned last_layer) 435848b8605Smrg{ 436848b8605Smrg struct r600_context *rctx = (struct r600_context *)ctx; 437848b8605Smrg struct r600_texture *rtex = (struct r600_texture*)tex; 438848b8605Smrg 439b8e80941Smrg if (rtex->db_compatible) { 440b8e80941Smrg if (r600_can_sample_zs(rtex, false)) { 441b8e80941Smrg r600_blit_decompress_depth_in_place(rctx, rtex, false, 442848b8605Smrg level, level, 443848b8605Smrg first_layer, last_layer); 444b8e80941Smrg if (rtex->surface.has_stencil) { 445b8e80941Smrg r600_blit_decompress_depth_in_place(rctx, rtex, true, 446b8e80941Smrg level, level, 447b8e80941Smrg first_layer, last_layer); 448b8e80941Smrg } 449848b8605Smrg } else { 450848b8605Smrg if (!r600_init_flushed_depth_texture(ctx, tex, NULL)) 451848b8605Smrg return false; /* error */ 452848b8605Smrg 453848b8605Smrg r600_blit_decompress_depth(ctx, rtex, NULL, 454848b8605Smrg level, level, 455848b8605Smrg first_layer, last_layer, 456848b8605Smrg 0, u_max_sample(tex)); 457848b8605Smrg } 458848b8605Smrg } else if (rtex->cmask.size) { 459848b8605Smrg r600_blit_decompress_color(ctx, rtex, level, level, 460848b8605Smrg first_layer, last_layer); 461848b8605Smrg } 462848b8605Smrg return true; 463848b8605Smrg} 464848b8605Smrg 465848b8605Smrgstatic void r600_clear(struct pipe_context *ctx, unsigned buffers, 466848b8605Smrg const union pipe_color_union *color, 467848b8605Smrg double depth, unsigned stencil) 468848b8605Smrg{ 469848b8605Smrg struct r600_context *rctx = (struct r600_context *)ctx; 470848b8605Smrg struct pipe_framebuffer_state *fb = &rctx->framebuffer.state; 471848b8605Smrg 472848b8605Smrg if (buffers & PIPE_CLEAR_COLOR && rctx->b.chip_class >= EVERGREEN) { 473848b8605Smrg evergreen_do_fast_color_clear(&rctx->b, fb, &rctx->framebuffer.atom, 474b8e80941Smrg &buffers, NULL, color); 475b8e80941Smrg if (!buffers) 476b8e80941Smrg return; /* all buffers have been fast cleared */ 477848b8605Smrg } 478848b8605Smrg 479848b8605Smrg if (buffers & PIPE_CLEAR_COLOR) { 480848b8605Smrg int i; 481848b8605Smrg 482848b8605Smrg /* These buffers cannot use fast clear, make sure to disable expansion. */ 483848b8605Smrg for (i = 0; i < fb->nr_cbufs; i++) { 484848b8605Smrg struct r600_texture *tex; 485848b8605Smrg 486848b8605Smrg /* If not clearing this buffer, skip. */ 487848b8605Smrg if (!(buffers & (PIPE_CLEAR_COLOR0 << i))) 488848b8605Smrg continue; 489848b8605Smrg 490848b8605Smrg if (!fb->cbufs[i]) 491848b8605Smrg continue; 492848b8605Smrg 493848b8605Smrg tex = (struct r600_texture *)fb->cbufs[i]->texture; 494848b8605Smrg if (tex->fmask.size == 0) 495848b8605Smrg tex->dirty_level_mask &= ~(1 << fb->cbufs[i]->u.tex.level); 496848b8605Smrg } 497848b8605Smrg } 498848b8605Smrg 499848b8605Smrg /* if hyperz enabled just clear hyperz */ 500848b8605Smrg if (fb->zsbuf && (buffers & PIPE_CLEAR_DEPTH)) { 501848b8605Smrg struct r600_texture *rtex; 502848b8605Smrg unsigned level = fb->zsbuf->u.tex.level; 503848b8605Smrg 504848b8605Smrg rtex = (struct r600_texture*)fb->zsbuf->texture; 505848b8605Smrg 506848b8605Smrg /* We can't use hyperz fast clear if each slice of a texture 507848b8605Smrg * array are clear to different value. To simplify code just 508848b8605Smrg * disable fast clear for texture array. 509848b8605Smrg */ 510b8e80941Smrg if (r600_htile_enabled(rtex, level) && 511b8e80941Smrg fb->zsbuf->u.tex.first_layer == 0 && 512b8e80941Smrg fb->zsbuf->u.tex.last_layer == util_max_layer(&rtex->resource.b.b, level)) { 513848b8605Smrg if (rtex->depth_clear_value != depth) { 514848b8605Smrg rtex->depth_clear_value = depth; 515b8e80941Smrg r600_mark_atom_dirty(rctx, &rctx->db_state.atom); 516848b8605Smrg } 517848b8605Smrg rctx->db_misc_state.htile_clear = true; 518b8e80941Smrg r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom); 519848b8605Smrg } 520848b8605Smrg } 521848b8605Smrg 522848b8605Smrg r600_blitter_begin(ctx, R600_CLEAR); 523848b8605Smrg util_blitter_clear(rctx->blitter, fb->width, fb->height, 524848b8605Smrg util_framebuffer_get_num_layers(fb), 525848b8605Smrg buffers, color, depth, stencil); 526848b8605Smrg r600_blitter_end(ctx); 527848b8605Smrg 528848b8605Smrg /* disable fast clear */ 529848b8605Smrg if (rctx->db_misc_state.htile_clear) { 530848b8605Smrg rctx->db_misc_state.htile_clear = false; 531b8e80941Smrg r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom); 532848b8605Smrg } 533848b8605Smrg} 534848b8605Smrg 535848b8605Smrgstatic void r600_clear_render_target(struct pipe_context *ctx, 536848b8605Smrg struct pipe_surface *dst, 537848b8605Smrg const union pipe_color_union *color, 538848b8605Smrg unsigned dstx, unsigned dsty, 539b8e80941Smrg unsigned width, unsigned height, 540b8e80941Smrg bool render_condition_enabled) 541848b8605Smrg{ 542848b8605Smrg struct r600_context *rctx = (struct r600_context *)ctx; 543848b8605Smrg 544b8e80941Smrg r600_blitter_begin(ctx, R600_CLEAR_SURFACE | 545b8e80941Smrg (render_condition_enabled ? 0 : R600_DISABLE_RENDER_COND)); 546848b8605Smrg util_blitter_clear_render_target(rctx->blitter, dst, color, 547848b8605Smrg dstx, dsty, width, height); 548848b8605Smrg r600_blitter_end(ctx); 549848b8605Smrg} 550848b8605Smrg 551848b8605Smrgstatic void r600_clear_depth_stencil(struct pipe_context *ctx, 552848b8605Smrg struct pipe_surface *dst, 553848b8605Smrg unsigned clear_flags, 554848b8605Smrg double depth, 555848b8605Smrg unsigned stencil, 556848b8605Smrg unsigned dstx, unsigned dsty, 557b8e80941Smrg unsigned width, unsigned height, 558b8e80941Smrg bool render_condition_enabled) 559848b8605Smrg{ 560848b8605Smrg struct r600_context *rctx = (struct r600_context *)ctx; 561848b8605Smrg 562b8e80941Smrg r600_blitter_begin(ctx, R600_CLEAR_SURFACE | 563b8e80941Smrg (render_condition_enabled ? 0 : R600_DISABLE_RENDER_COND)); 564848b8605Smrg util_blitter_clear_depth_stencil(rctx->blitter, dst, clear_flags, depth, stencil, 565848b8605Smrg dstx, dsty, width, height); 566848b8605Smrg r600_blitter_end(ctx); 567848b8605Smrg} 568848b8605Smrg 569848b8605Smrgstatic void r600_copy_buffer(struct pipe_context *ctx, struct pipe_resource *dst, unsigned dstx, 570848b8605Smrg struct pipe_resource *src, const struct pipe_box *src_box) 571848b8605Smrg{ 572848b8605Smrg struct r600_context *rctx = (struct r600_context*)ctx; 573848b8605Smrg 574848b8605Smrg if (rctx->screen->b.has_cp_dma) { 575848b8605Smrg r600_cp_dma_copy_buffer(rctx, dst, dstx, src, src_box->x, src_box->width); 576848b8605Smrg } 577848b8605Smrg else if (rctx->screen->b.has_streamout && 578848b8605Smrg /* Require 4-byte alignment. */ 579848b8605Smrg dstx % 4 == 0 && src_box->x % 4 == 0 && src_box->width % 4 == 0) { 580848b8605Smrg 581848b8605Smrg r600_blitter_begin(ctx, R600_COPY_BUFFER); 582848b8605Smrg util_blitter_copy_buffer(rctx->blitter, dst, dstx, src, src_box->x, src_box->width); 583848b8605Smrg r600_blitter_end(ctx); 584848b8605Smrg } else { 585848b8605Smrg util_resource_copy_region(ctx, dst, 0, dstx, 0, 0, src, 0, src_box); 586848b8605Smrg } 587848b8605Smrg} 588848b8605Smrg 589848b8605Smrg/** 590848b8605Smrg * Global buffers are not really resources, they are are actually offsets 591848b8605Smrg * into a single global resource (r600_screen::global_pool). The means 592b8e80941Smrg * they don't have their own buf handle, so they cannot be passed 593848b8605Smrg * to r600_copy_buffer() and must be handled separately. 594848b8605Smrg */ 595848b8605Smrgstatic void r600_copy_global_buffer(struct pipe_context *ctx, 596848b8605Smrg struct pipe_resource *dst, unsigned 597848b8605Smrg dstx, struct pipe_resource *src, 598848b8605Smrg const struct pipe_box *src_box) 599848b8605Smrg{ 600b8e80941Smrg struct r600_context *rctx = (struct r600_context*)ctx; 601b8e80941Smrg struct compute_memory_pool *pool = rctx->screen->global_pool; 602b8e80941Smrg struct pipe_box new_src_box = *src_box; 603b8e80941Smrg 604b8e80941Smrg if (src->bind & PIPE_BIND_GLOBAL) { 605b8e80941Smrg struct r600_resource_global *rsrc = 606b8e80941Smrg (struct r600_resource_global *)src; 607b8e80941Smrg struct compute_memory_item *item = rsrc->chunk; 608b8e80941Smrg 609b8e80941Smrg if (is_item_in_pool(item)) { 610b8e80941Smrg new_src_box.x += 4 * item->start_in_dw; 611b8e80941Smrg src = (struct pipe_resource *)pool->bo; 612b8e80941Smrg } else { 613b8e80941Smrg if (item->real_buffer == NULL) { 614b8e80941Smrg item->real_buffer = 615b8e80941Smrg r600_compute_buffer_alloc_vram(pool->screen, 616b8e80941Smrg item->size_in_dw * 4); 617b8e80941Smrg } 618b8e80941Smrg src = (struct pipe_resource*)item->real_buffer; 619b8e80941Smrg } 620b8e80941Smrg } 621b8e80941Smrg if (dst->bind & PIPE_BIND_GLOBAL) { 622b8e80941Smrg struct r600_resource_global *rdst = 623b8e80941Smrg (struct r600_resource_global *)dst; 624b8e80941Smrg struct compute_memory_item *item = rdst->chunk; 625b8e80941Smrg 626b8e80941Smrg if (is_item_in_pool(item)) { 627b8e80941Smrg dstx += 4 * item->start_in_dw; 628b8e80941Smrg dst = (struct pipe_resource *)pool->bo; 629b8e80941Smrg } else { 630b8e80941Smrg if (item->real_buffer == NULL) { 631b8e80941Smrg item->real_buffer = 632b8e80941Smrg r600_compute_buffer_alloc_vram(pool->screen, 633b8e80941Smrg item->size_in_dw * 4); 634b8e80941Smrg } 635b8e80941Smrg dst = (struct pipe_resource*)item->real_buffer; 636b8e80941Smrg } 637b8e80941Smrg } 638b8e80941Smrg 639b8e80941Smrg r600_copy_buffer(ctx, dst, dstx, src, &new_src_box); 640848b8605Smrg} 641848b8605Smrg 642848b8605Smrgstatic void r600_clear_buffer(struct pipe_context *ctx, struct pipe_resource *dst, 643b8e80941Smrg uint64_t offset, uint64_t size, unsigned value, 644b8e80941Smrg enum r600_coherency coher) 645848b8605Smrg{ 646848b8605Smrg struct r600_context *rctx = (struct r600_context*)ctx; 647848b8605Smrg 648848b8605Smrg if (rctx->screen->b.has_cp_dma && 649848b8605Smrg rctx->b.chip_class >= EVERGREEN && 650848b8605Smrg offset % 4 == 0 && size % 4 == 0) { 651b8e80941Smrg evergreen_cp_dma_clear_buffer(rctx, dst, offset, size, value, coher); 652848b8605Smrg } else if (rctx->screen->b.has_streamout && offset % 4 == 0 && size % 4 == 0) { 653848b8605Smrg union pipe_color_union clear_value; 654848b8605Smrg clear_value.ui[0] = value; 655848b8605Smrg 656848b8605Smrg r600_blitter_begin(ctx, R600_DISABLE_RENDER_COND); 657848b8605Smrg util_blitter_clear_buffer(rctx->blitter, dst, offset, size, 658848b8605Smrg 1, &clear_value); 659848b8605Smrg r600_blitter_end(ctx); 660848b8605Smrg } else { 661848b8605Smrg uint32_t *map = r600_buffer_map_sync_with_rings(&rctx->b, r600_resource(dst), 662848b8605Smrg PIPE_TRANSFER_WRITE); 663b8e80941Smrg map += offset / 4; 664848b8605Smrg size /= 4; 665848b8605Smrg for (unsigned i = 0; i < size; i++) 666848b8605Smrg *map++ = value; 667848b8605Smrg } 668848b8605Smrg} 669848b8605Smrg 670b8e80941Smrgvoid r600_resource_copy_region(struct pipe_context *ctx, 671b8e80941Smrg struct pipe_resource *dst, 672b8e80941Smrg unsigned dst_level, 673b8e80941Smrg unsigned dstx, unsigned dsty, unsigned dstz, 674b8e80941Smrg struct pipe_resource *src, 675b8e80941Smrg unsigned src_level, 676b8e80941Smrg const struct pipe_box *src_box) 677848b8605Smrg{ 678848b8605Smrg struct r600_context *rctx = (struct r600_context *)ctx; 679848b8605Smrg struct pipe_surface *dst_view, dst_templ; 680848b8605Smrg struct pipe_sampler_view src_templ, *src_view; 681848b8605Smrg unsigned dst_width, dst_height, src_width0, src_height0, src_widthFL, src_heightFL; 682848b8605Smrg unsigned src_force_level = 0; 683848b8605Smrg struct pipe_box sbox, dstbox; 684848b8605Smrg 685848b8605Smrg /* Handle buffers first. */ 686848b8605Smrg if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { 687848b8605Smrg if ((src->bind & PIPE_BIND_GLOBAL) || 688848b8605Smrg (dst->bind & PIPE_BIND_GLOBAL)) { 689848b8605Smrg r600_copy_global_buffer(ctx, dst, dstx, src, src_box); 690848b8605Smrg } else { 691848b8605Smrg r600_copy_buffer(ctx, dst, dstx, src, src_box); 692848b8605Smrg } 693848b8605Smrg return; 694848b8605Smrg } 695848b8605Smrg 696848b8605Smrg assert(u_max_sample(dst) == u_max_sample(src)); 697848b8605Smrg 698848b8605Smrg /* The driver doesn't decompress resources automatically while 699848b8605Smrg * u_blitter is rendering. */ 700848b8605Smrg if (!r600_decompress_subresource(ctx, src, src_level, 701848b8605Smrg src_box->z, src_box->z + src_box->depth - 1)) { 702848b8605Smrg return; /* error */ 703848b8605Smrg } 704848b8605Smrg 705848b8605Smrg dst_width = u_minify(dst->width0, dst_level); 706848b8605Smrg dst_height = u_minify(dst->height0, dst_level); 707848b8605Smrg src_width0 = src->width0; 708848b8605Smrg src_height0 = src->height0; 709848b8605Smrg src_widthFL = u_minify(src->width0, src_level); 710848b8605Smrg src_heightFL = u_minify(src->height0, src_level); 711848b8605Smrg 712848b8605Smrg util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz); 713b8e80941Smrg util_blitter_default_src_texture(rctx->blitter, &src_templ, src, src_level); 714848b8605Smrg 715b8e80941Smrg if (util_format_is_compressed(src->format) || 716b8e80941Smrg util_format_is_compressed(dst->format)) { 717848b8605Smrg unsigned blocksize = util_format_get_blocksize(src->format); 718848b8605Smrg 719848b8605Smrg if (blocksize == 8) 720848b8605Smrg src_templ.format = PIPE_FORMAT_R16G16B16A16_UINT; /* 64-bit block */ 721848b8605Smrg else 722848b8605Smrg src_templ.format = PIPE_FORMAT_R32G32B32A32_UINT; /* 128-bit block */ 723848b8605Smrg dst_templ.format = src_templ.format; 724848b8605Smrg 725848b8605Smrg dst_width = util_format_get_nblocksx(dst->format, dst_width); 726848b8605Smrg dst_height = util_format_get_nblocksy(dst->format, dst_height); 727848b8605Smrg src_width0 = util_format_get_nblocksx(src->format, src_width0); 728848b8605Smrg src_height0 = util_format_get_nblocksy(src->format, src_height0); 729848b8605Smrg src_widthFL = util_format_get_nblocksx(src->format, src_widthFL); 730848b8605Smrg src_heightFL = util_format_get_nblocksy(src->format, src_heightFL); 731848b8605Smrg 732848b8605Smrg dstx = util_format_get_nblocksx(dst->format, dstx); 733848b8605Smrg dsty = util_format_get_nblocksy(dst->format, dsty); 734848b8605Smrg 735848b8605Smrg sbox.x = util_format_get_nblocksx(src->format, src_box->x); 736848b8605Smrg sbox.y = util_format_get_nblocksy(src->format, src_box->y); 737848b8605Smrg sbox.z = src_box->z; 738848b8605Smrg sbox.width = util_format_get_nblocksx(src->format, src_box->width); 739848b8605Smrg sbox.height = util_format_get_nblocksy(src->format, src_box->height); 740848b8605Smrg sbox.depth = src_box->depth; 741848b8605Smrg src_box = &sbox; 742848b8605Smrg 743848b8605Smrg src_force_level = src_level; 744848b8605Smrg } else if (!util_blitter_is_copy_supported(rctx->blitter, dst, src)) { 745848b8605Smrg if (util_format_is_subsampled_422(src->format)) { 746848b8605Smrg 747848b8605Smrg src_templ.format = PIPE_FORMAT_R8G8B8A8_UINT; 748848b8605Smrg dst_templ.format = PIPE_FORMAT_R8G8B8A8_UINT; 749848b8605Smrg 750848b8605Smrg dst_width = util_format_get_nblocksx(dst->format, dst_width); 751848b8605Smrg src_width0 = util_format_get_nblocksx(src->format, src_width0); 752848b8605Smrg src_widthFL = util_format_get_nblocksx(src->format, src_widthFL); 753848b8605Smrg 754848b8605Smrg dstx = util_format_get_nblocksx(dst->format, dstx); 755848b8605Smrg 756848b8605Smrg sbox = *src_box; 757848b8605Smrg sbox.x = util_format_get_nblocksx(src->format, src_box->x); 758848b8605Smrg sbox.width = util_format_get_nblocksx(src->format, src_box->width); 759848b8605Smrg src_box = &sbox; 760848b8605Smrg } else { 761848b8605Smrg unsigned blocksize = util_format_get_blocksize(src->format); 762848b8605Smrg 763848b8605Smrg switch (blocksize) { 764848b8605Smrg case 1: 765848b8605Smrg dst_templ.format = PIPE_FORMAT_R8_UNORM; 766848b8605Smrg src_templ.format = PIPE_FORMAT_R8_UNORM; 767848b8605Smrg break; 768b8e80941Smrg case 2: 769848b8605Smrg dst_templ.format = PIPE_FORMAT_R8G8_UNORM; 770848b8605Smrg src_templ.format = PIPE_FORMAT_R8G8_UNORM; 771848b8605Smrg break; 772848b8605Smrg case 4: 773848b8605Smrg dst_templ.format = PIPE_FORMAT_R8G8B8A8_UNORM; 774848b8605Smrg src_templ.format = PIPE_FORMAT_R8G8B8A8_UNORM; 775848b8605Smrg break; 776b8e80941Smrg case 8: 777b8e80941Smrg dst_templ.format = PIPE_FORMAT_R16G16B16A16_UINT; 778b8e80941Smrg src_templ.format = PIPE_FORMAT_R16G16B16A16_UINT; 779b8e80941Smrg break; 780b8e80941Smrg case 16: 781b8e80941Smrg dst_templ.format = PIPE_FORMAT_R32G32B32A32_UINT; 782b8e80941Smrg src_templ.format = PIPE_FORMAT_R32G32B32A32_UINT; 783b8e80941Smrg break; 784848b8605Smrg default: 785848b8605Smrg fprintf(stderr, "Unhandled format %s with blocksize %u\n", 786848b8605Smrg util_format_short_name(src->format), blocksize); 787848b8605Smrg assert(0); 788848b8605Smrg } 789848b8605Smrg } 790848b8605Smrg } 791848b8605Smrg 792b8e80941Smrg dst_view = r600_create_surface_custom(ctx, dst, &dst_templ, 793b8e80941Smrg /* we don't care about these two for r600g */ 794b8e80941Smrg dst->width0, dst->height0, 795b8e80941Smrg dst_width, dst_height); 796848b8605Smrg 797848b8605Smrg if (rctx->b.chip_class >= EVERGREEN) { 798848b8605Smrg src_view = evergreen_create_sampler_view_custom(ctx, src, &src_templ, 799848b8605Smrg src_width0, src_height0, 800848b8605Smrg src_force_level); 801848b8605Smrg } else { 802848b8605Smrg src_view = r600_create_sampler_view_custom(ctx, src, &src_templ, 803848b8605Smrg src_widthFL, src_heightFL); 804848b8605Smrg } 805848b8605Smrg 806848b8605Smrg u_box_3d(dstx, dsty, dstz, abs(src_box->width), abs(src_box->height), 807848b8605Smrg abs(src_box->depth), &dstbox); 808848b8605Smrg 809848b8605Smrg /* Copy. */ 810848b8605Smrg r600_blitter_begin(ctx, R600_COPY_TEXTURE); 811848b8605Smrg util_blitter_blit_generic(rctx->blitter, dst_view, &dstbox, 812848b8605Smrg src_view, src_box, src_width0, src_height0, 813b8e80941Smrg PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL, 814b8e80941Smrg FALSE); 815848b8605Smrg r600_blitter_end(ctx); 816848b8605Smrg 817848b8605Smrg pipe_surface_reference(&dst_view, NULL); 818848b8605Smrg pipe_sampler_view_reference(&src_view, NULL); 819848b8605Smrg} 820848b8605Smrg 821848b8605Smrgstatic bool do_hardware_msaa_resolve(struct pipe_context *ctx, 822848b8605Smrg const struct pipe_blit_info *info) 823848b8605Smrg{ 824848b8605Smrg struct r600_context *rctx = (struct r600_context*)ctx; 825848b8605Smrg struct r600_texture *dst = (struct r600_texture*)info->dst.resource; 826848b8605Smrg unsigned dst_width = u_minify(info->dst.resource->width0, info->dst.level); 827848b8605Smrg unsigned dst_height = u_minify(info->dst.resource->height0, info->dst.level); 828b8e80941Smrg enum pipe_format format = info->src.format; 829848b8605Smrg unsigned sample_mask = 830848b8605Smrg rctx->b.chip_class == CAYMAN ? ~0 : 831848b8605Smrg ((1ull << MAX2(1, info->src.resource->nr_samples)) - 1); 832b8e80941Smrg struct pipe_resource *tmp, templ; 833b8e80941Smrg struct pipe_blit_info blit; 834b8e80941Smrg 835b8e80941Smrg /* Check basic requirements for hw resolve. */ 836b8e80941Smrg if (!(info->src.resource->nr_samples > 1 && 837b8e80941Smrg info->dst.resource->nr_samples <= 1 && 838b8e80941Smrg !util_format_is_pure_integer(format) && 839b8e80941Smrg !util_format_is_depth_or_stencil(format) && 840b8e80941Smrg util_max_layer(info->src.resource, 0) == 0)) 841b8e80941Smrg return false; 842b8e80941Smrg 843b8e80941Smrg /* Check the remaining requirements for hw resolve. */ 844b8e80941Smrg if (util_max_layer(info->dst.resource, info->dst.level) == 0 && 845b8e80941Smrg util_is_format_compatible(util_format_description(info->src.format), 846b8e80941Smrg util_format_description(info->dst.format)) && 847848b8605Smrg !info->scissor_enable && 848848b8605Smrg (info->mask & PIPE_MASK_RGBA) == PIPE_MASK_RGBA && 849848b8605Smrg dst_width == info->src.resource->width0 && 850848b8605Smrg dst_height == info->src.resource->height0 && 851848b8605Smrg info->dst.box.x == 0 && 852848b8605Smrg info->dst.box.y == 0 && 853848b8605Smrg info->dst.box.width == dst_width && 854848b8605Smrg info->dst.box.height == dst_height && 855848b8605Smrg info->dst.box.depth == 1 && 856848b8605Smrg info->src.box.x == 0 && 857848b8605Smrg info->src.box.y == 0 && 858848b8605Smrg info->src.box.width == dst_width && 859848b8605Smrg info->src.box.height == dst_height && 860848b8605Smrg info->src.box.depth == 1 && 861b8e80941Smrg dst->surface.u.legacy.level[info->dst.level].mode >= RADEON_SURF_MODE_1D && 862848b8605Smrg (!dst->cmask.size || !dst->dirty_level_mask) /* dst cannot be fast-cleared */) { 863848b8605Smrg r600_blitter_begin(ctx, R600_COLOR_RESOLVE | 864848b8605Smrg (info->render_condition_enable ? 0 : R600_DISABLE_RENDER_COND)); 865848b8605Smrg util_blitter_custom_resolve_color(rctx->blitter, 866848b8605Smrg info->dst.resource, info->dst.level, 867848b8605Smrg info->dst.box.z, 868848b8605Smrg info->src.resource, info->src.box.z, 869848b8605Smrg sample_mask, rctx->custom_blend_resolve, 870848b8605Smrg format); 871848b8605Smrg r600_blitter_end(ctx); 872848b8605Smrg return true; 873848b8605Smrg } 874b8e80941Smrg 875b8e80941Smrg /* Shader-based resolve is VERY SLOW. Instead, resolve into 876b8e80941Smrg * a temporary texture and blit. 877b8e80941Smrg */ 878b8e80941Smrg memset(&templ, 0, sizeof(templ)); 879b8e80941Smrg templ.target = PIPE_TEXTURE_2D; 880b8e80941Smrg templ.format = info->src.resource->format; 881b8e80941Smrg templ.width0 = info->src.resource->width0; 882b8e80941Smrg templ.height0 = info->src.resource->height0; 883b8e80941Smrg templ.depth0 = 1; 884b8e80941Smrg templ.array_size = 1; 885b8e80941Smrg templ.usage = PIPE_USAGE_DEFAULT; 886b8e80941Smrg templ.flags = R600_RESOURCE_FLAG_FORCE_TILING; 887b8e80941Smrg 888b8e80941Smrg tmp = ctx->screen->resource_create(ctx->screen, &templ); 889b8e80941Smrg if (!tmp) 890b8e80941Smrg return false; 891b8e80941Smrg 892b8e80941Smrg /* resolve */ 893b8e80941Smrg r600_blitter_begin(ctx, R600_COLOR_RESOLVE | 894b8e80941Smrg (info->render_condition_enable ? 0 : R600_DISABLE_RENDER_COND)); 895b8e80941Smrg util_blitter_custom_resolve_color(rctx->blitter, tmp, 0, 0, 896b8e80941Smrg info->src.resource, info->src.box.z, 897b8e80941Smrg sample_mask, rctx->custom_blend_resolve, 898b8e80941Smrg format); 899b8e80941Smrg r600_blitter_end(ctx); 900b8e80941Smrg 901b8e80941Smrg /* blit */ 902b8e80941Smrg blit = *info; 903b8e80941Smrg blit.src.resource = tmp; 904b8e80941Smrg blit.src.box.z = 0; 905b8e80941Smrg 906b8e80941Smrg r600_blitter_begin(ctx, R600_BLIT | 907b8e80941Smrg (info->render_condition_enable ? 0 : R600_DISABLE_RENDER_COND)); 908b8e80941Smrg util_blitter_blit(rctx->blitter, &blit); 909b8e80941Smrg r600_blitter_end(ctx); 910b8e80941Smrg 911b8e80941Smrg pipe_resource_reference(&tmp, NULL); 912b8e80941Smrg return true; 913848b8605Smrg} 914848b8605Smrg 915848b8605Smrgstatic void r600_blit(struct pipe_context *ctx, 916848b8605Smrg const struct pipe_blit_info *info) 917848b8605Smrg{ 918848b8605Smrg struct r600_context *rctx = (struct r600_context*)ctx; 919b8e80941Smrg struct r600_texture *rdst = (struct r600_texture *)info->dst.resource; 920848b8605Smrg 921848b8605Smrg if (do_hardware_msaa_resolve(ctx, info)) { 922848b8605Smrg return; 923848b8605Smrg } 924848b8605Smrg 925b8e80941Smrg /* Using SDMA for copying to a linear texture in GTT is much faster. 926b8e80941Smrg * This improves DRI PRIME performance. 927b8e80941Smrg * 928b8e80941Smrg * resource_copy_region can't do this yet, because dma_copy calls it 929b8e80941Smrg * on failure (recursion). 930b8e80941Smrg */ 931b8e80941Smrg if (rdst->surface.u.legacy.level[info->dst.level].mode == 932b8e80941Smrg RADEON_SURF_MODE_LINEAR_ALIGNED && 933b8e80941Smrg rctx->b.dma_copy && 934b8e80941Smrg util_can_blit_via_copy_region(info, false)) { 935b8e80941Smrg rctx->b.dma_copy(ctx, info->dst.resource, info->dst.level, 936b8e80941Smrg info->dst.box.x, info->dst.box.y, 937b8e80941Smrg info->dst.box.z, 938b8e80941Smrg info->src.resource, info->src.level, 939b8e80941Smrg &info->src.box); 940b8e80941Smrg return; 941b8e80941Smrg } 942b8e80941Smrg 943848b8605Smrg assert(util_blitter_is_blit_supported(rctx->blitter, info)); 944848b8605Smrg 945848b8605Smrg /* The driver doesn't decompress resources automatically while 946848b8605Smrg * u_blitter is rendering. */ 947848b8605Smrg if (!r600_decompress_subresource(ctx, info->src.resource, info->src.level, 948848b8605Smrg info->src.box.z, 949848b8605Smrg info->src.box.z + info->src.box.depth - 1)) { 950848b8605Smrg return; /* error */ 951848b8605Smrg } 952848b8605Smrg 953b8e80941Smrg if (rctx->screen->b.debug_flags & DBG_FORCE_DMA && 954b8e80941Smrg util_try_blit_via_copy_region(ctx, info)) 955b8e80941Smrg return; 956b8e80941Smrg 957848b8605Smrg r600_blitter_begin(ctx, R600_BLIT | 958848b8605Smrg (info->render_condition_enable ? 0 : R600_DISABLE_RENDER_COND)); 959848b8605Smrg util_blitter_blit(rctx->blitter, info); 960848b8605Smrg r600_blitter_end(ctx); 961848b8605Smrg} 962848b8605Smrg 963848b8605Smrgstatic void r600_flush_resource(struct pipe_context *ctx, 964848b8605Smrg struct pipe_resource *res) 965848b8605Smrg{ 966848b8605Smrg struct r600_texture *rtex = (struct r600_texture*)res; 967848b8605Smrg 968848b8605Smrg assert(res->target != PIPE_BUFFER); 969848b8605Smrg 970848b8605Smrg if (!rtex->is_depth && rtex->cmask.size) { 971848b8605Smrg r600_blit_decompress_color(ctx, rtex, 0, res->last_level, 972848b8605Smrg 0, util_max_layer(res, 0)); 973848b8605Smrg } 974848b8605Smrg} 975848b8605Smrg 976848b8605Smrgvoid r600_init_blit_functions(struct r600_context *rctx) 977848b8605Smrg{ 978848b8605Smrg rctx->b.b.clear = r600_clear; 979848b8605Smrg rctx->b.b.clear_render_target = r600_clear_render_target; 980848b8605Smrg rctx->b.b.clear_depth_stencil = r600_clear_depth_stencil; 981848b8605Smrg rctx->b.b.resource_copy_region = r600_resource_copy_region; 982848b8605Smrg rctx->b.b.blit = r600_blit; 983848b8605Smrg rctx->b.b.flush_resource = r600_flush_resource; 984848b8605Smrg rctx->b.clear_buffer = r600_clear_buffer; 985848b8605Smrg rctx->b.blit_decompress_depth = r600_blit_decompress_depth; 986848b8605Smrg} 987