[Mesa-dev] [PATCH 12/14] gallium/radeon: generalize the function for in-place texture reallocation
Marek Olšák
maraeo at gmail.com
Thu Jun 29 19:47:47 UTC 2017
From: Marek Olšák <marek.olsak at 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
More information about the mesa-dev
mailing list