From: Marek Olšák <marek.ol...@amd.com> --- src/gallium/drivers/radeon/r600_texture.c | 64 +++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 21 deletions(-)
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index e21dc37..40cb8c0 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -441,86 +441,107 @@ bool r600_texture_disable_dcc(struct r600_common_context *rctx, /* Decompress DCC. */ rctx->decompress_dcc(&rctx->b, rtex); rctx->b.flush(&rctx->b, NULL, 0); if (&rctx->b == rscreen->aux_context) mtx_unlock(&rscreen->aux_context_lock); return r600_texture_discard_dcc(rscreen, rtex); } -static void r600_degrade_tile_mode_to_linear(struct r600_common_context *rctx, - struct r600_texture *rtex, - bool invalidate_storage) +static void r600_reallocate_texture_inplace(struct r600_common_context *rctx, + struct r600_texture *rtex, + unsigned new_bind_flag, + bool invalidate_storage) { struct pipe_screen *screen = rctx->b.screen; struct r600_texture *new_tex; struct pipe_resource templ = rtex->resource.b.b; unsigned i; - templ.bind |= PIPE_BIND_LINEAR; + templ.bind |= new_bind_flag; /* r600g doesn't react to dirty_tex_descriptor_counter */ if (rctx->chip_class < SI) return; - if (rtex->resource.b.is_shared || - rtex->surface.is_linear) + if (rtex->resource.b.is_shared) return; - /* This fails with MSAA, depth, and compressed textures. */ - if (r600_choose_tiling(rctx->screen, &templ) != - RADEON_SURF_MODE_LINEAR_ALIGNED) - return; + if (new_bind_flag == PIPE_BIND_LINEAR) { + if (rtex->surface.is_linear) + return; + + /* This fails with MSAA, depth, and compressed textures. */ + if (r600_choose_tiling(rctx->screen, &templ) != + RADEON_SURF_MODE_LINEAR_ALIGNED) + return; + } new_tex = (struct r600_texture*)screen->resource_create(screen, &templ); if (!new_tex) return; /* Copy the pixels to the new texture. */ if (!invalidate_storage) { for (i = 0; i <= templ.last_level; i++) { struct pipe_box box; u_box_3d(0, 0, 0, u_minify(templ.width0, i), u_minify(templ.height0, i), util_max_layer(&templ, i) + 1, &box); rctx->dma_copy(&rctx->b, &new_tex->resource.b.b, i, 0, 0, 0, &rtex->resource.b.b, i, &box); } } - r600_texture_discard_cmask(rctx->screen, rtex); - r600_texture_discard_dcc(rctx->screen, rtex); + if (new_bind_flag == PIPE_BIND_LINEAR) { + r600_texture_discard_cmask(rctx->screen, rtex); + r600_texture_discard_dcc(rctx->screen, rtex); + } /* Replace the structure fields of rtex. */ rtex->resource.b.b.bind = templ.bind; pb_reference(&rtex->resource.buf, new_tex->resource.buf); rtex->resource.gpu_address = new_tex->resource.gpu_address; rtex->resource.vram_usage = new_tex->resource.vram_usage; rtex->resource.gart_usage = new_tex->resource.gart_usage; rtex->resource.bo_size = new_tex->resource.bo_size; rtex->resource.bo_alignment = new_tex->resource.bo_alignment; rtex->resource.domains = new_tex->resource.domains; rtex->resource.flags = new_tex->resource.flags; rtex->size = new_tex->size; + rtex->db_render_format = new_tex->db_render_format; + rtex->db_compatible = new_tex->db_compatible; + rtex->can_sample_z = new_tex->can_sample_z; + rtex->can_sample_s = new_tex->can_sample_s; rtex->surface = new_tex->surface; - rtex->non_disp_tiling = new_tex->non_disp_tiling; + rtex->fmask = new_tex->fmask; + rtex->cmask = new_tex->cmask; rtex->cb_color_info = new_tex->cb_color_info; - rtex->cmask = new_tex->cmask; /* needed even without CMASK */ + rtex->last_msaa_resolve_target_micro_mode = new_tex->last_msaa_resolve_target_micro_mode; + rtex->htile_offset = new_tex->htile_offset; + rtex->tc_compatible_htile = new_tex->tc_compatible_htile; + rtex->depth_cleared = new_tex->depth_cleared; + rtex->stencil_cleared = new_tex->stencil_cleared; + rtex->non_disp_tiling = new_tex->non_disp_tiling; + rtex->dcc_gather_statistics = new_tex->dcc_gather_statistics; + rtex->framebuffers_bound = new_tex->framebuffers_bound; - assert(!rtex->htile_offset); - assert(!rtex->cmask.size); - assert(!rtex->fmask.size); - assert(!rtex->dcc_offset); - assert(!rtex->is_depth); + if (new_bind_flag == PIPE_BIND_LINEAR) { + assert(!rtex->htile_offset); + assert(!rtex->cmask.size); + assert(!rtex->fmask.size); + assert(!rtex->dcc_offset); + assert(!rtex->is_depth); + } r600_texture_reference(&new_tex, NULL); p_atomic_inc(&rctx->screen->dirty_tex_counter); } static boolean r600_texture_get_handle(struct pipe_screen* screen, struct pipe_context *ctx, struct pipe_resource *resource, struct winsys_handle *whandle, @@ -1610,22 +1631,23 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx, * Only count uploads that are at least 4x4 pixels large. */ if (!rctx->screen->info.has_dedicated_vram && level == 0 && box->width >= 4 && box->height >= 4 && p_atomic_inc_return(&rtex->num_level0_transfers) == 10) { bool can_invalidate = r600_can_invalidate_texture(rctx->screen, rtex, usage, box); - r600_degrade_tile_mode_to_linear(rctx, rtex, - can_invalidate); + r600_reallocate_texture_inplace(rctx, rtex, + PIPE_BIND_LINEAR, + can_invalidate); } /* Tiled textures need to be converted into a linear texture for CPU * access. The staging texture is always linear and is placed in GART. * * Reading from VRAM or GTT WC is slow, always use the staging * texture in this case. * * Use the staging texture for uploads if the underlying BO * is busy. -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev