/* Each texture is an array of slices. Each slice is an array
* of mipmap levels. */
return box->z * rtex->surface.u.gfx9.surf_slice_size +
- ((rtex->surface.u.gfx9.surf_ymip_offset[level] +
- box->y / rtex->surface.blk_h) *
+ rtex->surface.u.gfx9.offset[level] +
+ (box->y / rtex->surface.blk_h *
rtex->surface.u.gfx9.surf_pitch +
box->x / rtex->surface.blk_w) * rtex->surface.bpe;
} else {
{
/* We can't disable DCC if it can be written by another process. */
return rtex->dcc_offset &&
- (!rtex->resource.is_shared ||
+ (!rtex->resource.b.is_shared ||
!(rtex->resource.external_usage & PIPE_HANDLE_USAGE_WRITE));
}
if (rctx->chip_class < SI)
return;
- if (rtex->resource.is_shared ||
+ if (rtex->resource.b.is_shared ||
rtex->surface.is_linear)
return;
unsigned usage)
{
struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;
- struct r600_common_context *rctx = (struct r600_common_context*)
- (ctx ? ctx : rscreen->aux_context);
+ struct r600_common_context *rctx;
struct r600_resource *res = (struct r600_resource*)resource;
struct r600_texture *rtex = (struct r600_texture*)resource;
struct radeon_bo_metadata metadata;
bool update_metadata = false;
unsigned stride, offset, slice_size;
+ ctx = threaded_context_unwrap_sync(ctx);
+ rctx = (struct r600_common_context*)(ctx ? ctx : rscreen->aux_context);
+
/* This is not supported now, but it might be required for OpenCL
* interop in the future.
*/
}
/* Set metadata. */
- if (!res->is_shared || update_metadata) {
+ if (!res->b.is_shared || update_metadata) {
r600_texture_init_metadata(rscreen, rtex, &metadata);
if (rscreen->query_opaque_metadata)
rscreen->query_opaque_metadata(rscreen, rtex,
}
}
- if (res->is_shared) {
+ if (res->b.is_shared) {
/* USAGE_EXPLICIT_FLUSH must be cleared if at least one user
* doesn't set it.
*/
if (!(usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH))
res->external_usage &= ~PIPE_HANDLE_USAGE_EXPLICIT_FLUSH;
} else {
- res->is_shared = true;
+ res->b.is_shared = true;
res->external_usage = usage;
}
if (!rtex)
return NULL;
- rtex->resource.is_shared = true;
+ rtex->resource.b.is_shared = true;
rtex->resource.external_usage = usage;
if (rscreen->apply_opaque_metadata)
/* Validate that addrlib arrived at the same surface parameters. */
if (rscreen->chip_class >= GFX9) {
- struct gfx9_surf_layout *gfx9 = &surface.u.gfx9;
-
- assert(metadata.u.gfx9.swizzle_mode == gfx9->surf.swizzle_mode);
+ assert(metadata.u.gfx9.swizzle_mode == surface.u.gfx9.surf.swizzle_mode);
}
return &rtex->resource.b.b;
{
/* r600g doesn't react to dirty_tex_descriptor_counter */
return rscreen->chip_class >= SI &&
- !rtex->resource.is_shared &&
+ !rtex->resource.b.is_shared &&
!(transfer_usage & PIPE_TRANSFER_READ) &&
rtex->resource.b.b.last_level == 0 &&
util_texrange_covers_whole_level(&rtex->resource.b.b, 0,
* Use the staging texture for uploads if the underlying BO
* is busy.
*/
- /* TODO: Linear CPU mipmap addressing is broken on GFX9: */
- if (!rtex->surface.is_linear ||
- (rctx->chip_class == GFX9 && level))
+ if (!rtex->surface.is_linear)
use_staging_texture = true;
else if (usage & PIPE_TRANSFER_READ)
use_staging_texture =
trans = CALLOC_STRUCT(r600_transfer);
if (!trans)
return NULL;
- pipe_resource_reference(&trans->transfer.resource, texture);
- trans->transfer.level = level;
- trans->transfer.usage = usage;
- trans->transfer.box = *box;
+ pipe_resource_reference(&trans->b.b.resource, texture);
+ trans->b.b.level = level;
+ trans->b.b.usage = usage;
+ trans->b.b.box = *box;
if (rtex->is_depth) {
struct r600_texture *staging_depth;
/* Just get the strides. */
r600_texture_get_offset(rctx->screen, staging_depth, level, NULL,
- &trans->transfer.stride,
- &trans->transfer.layer_stride);
+ &trans->b.b.stride,
+ &trans->b.b.layer_stride);
} else {
/* XXX: only readback the rectangle which is being mapped? */
/* XXX: when discard is true, no need to read back from depth texture */
offset = r600_texture_get_offset(rctx->screen, staging_depth,
level, box,
- &trans->transfer.stride,
- &trans->transfer.layer_stride);
+ &trans->b.b.stride,
+ &trans->b.b.layer_stride);
}
trans->staging = (struct r600_resource*)staging_depth;
/* Just get the strides. */
r600_texture_get_offset(rctx->screen, staging, 0, NULL,
- &trans->transfer.stride,
- &trans->transfer.layer_stride);
+ &trans->b.b.stride,
+ &trans->b.b.layer_stride);
if (usage & PIPE_TRANSFER_READ)
r600_copy_to_staging_texture(ctx, trans);
} else {
/* the resource is mapped directly */
offset = r600_texture_get_offset(rctx->screen, rtex, level, box,
- &trans->transfer.stride,
- &trans->transfer.layer_stride);
+ &trans->b.b.stride,
+ &trans->b.b.layer_stride);
buf = &rtex->resource;
}
return NULL;
}
- *ptransfer = &trans->transfer;
+ *ptransfer = &trans->b.b;
return map + offset;
}
type1 == type2;
}
+bool vi_dcc_formats_are_incompatible(struct pipe_resource *tex,
+ unsigned level,
+ enum pipe_format view_format)
+{
+ struct r600_texture *rtex = (struct r600_texture *)tex;
+
+ return vi_dcc_enabled(rtex, level) &&
+ !vi_dcc_formats_compatible(tex->format, view_format);
+}
+
+/* This can't be merged with the above function, because
+ * vi_dcc_formats_compatible should be called only when DCC is enabled. */
void vi_disable_dcc_if_incompatible_format(struct r600_common_context *rctx,
struct pipe_resource *tex,
unsigned level,
unsigned width0, unsigned height0,
unsigned width, unsigned height)
{
- struct r600_common_context *rctx = (struct r600_common_context*)pipe;
struct r600_surface *surface = CALLOC_STRUCT(r600_surface);
if (!surface)
surface->width0 = width0;
surface->height0 = height0;
- if (texture->target != PIPE_BUFFER)
- vi_disable_dcc_if_incompatible_format(rctx, texture,
- templ->u.tex.level,
- templ->format);
-
+ surface->dcc_incompatible =
+ texture->target != PIPE_BUFFER &&
+ vi_dcc_formats_are_incompatible(texture, templ->u.tex.level,
+ templ->format);
return &surface->base;
}
/* The intent is to use this with shared displayable back buffers,
* but it's not strictly limited only to them.
*/
- if (!tex->resource.is_shared ||
+ if (!tex->resource.b.is_shared ||
!(tex->resource.external_usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH) ||
tex->resource.b.b.target != PIPE_TEXTURE_2D ||
tex->resource.b.b.last_level > 0 ||
static void si_set_optimal_micro_tile_mode(struct r600_common_screen *rscreen,
struct r600_texture *rtex)
{
- if (rtex->resource.is_shared ||
+ if (rtex->resource.b.is_shared ||
rtex->resource.b.b.nr_samples <= 1 ||
rtex->surface.micro_tile_mode == rtex->last_msaa_resolve_target_micro_mode)
return;
if (rctx->render_cond)
return;
- /* TODO: fix CMASK and DCC fast clear */
- if (rctx->chip_class >= GFX9)
- return;
-
for (i = 0; i < fb->nr_cbufs; i++) {
struct r600_texture *tex;
unsigned clear_bit = PIPE_CLEAR_COLOR0 << i;
* because there is no way to communicate the clear color among
* all clients
*/
- if (tex->resource.is_shared &&
+ if (tex->resource.b.is_shared &&
!(tex->resource.external_usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH))
continue;
!(rctx->screen->debug_flags & DBG_NO_DCC_FB)) {
vi_separate_dcc_try_enable(rctx, tex);
- /* RB+ isn't supported with a CMASK-based clear, so all
- * clears are considered to be hypothetically slow
+ /* RB+ isn't supported with a CMASK clear only on Stoney,
+ * so all clears are considered to be hypothetically slow
* clears, which is weighed when determining whether to
* enable separate DCC.
*/
if (tex->dcc_gather_statistics &&
- rctx->screen->rbplus_allowed)
+ rctx->family == CHIP_STONEY)
tex->num_slow_clears++;
}
uint32_t reset_value;
bool clear_words_needed;
+ /* TODO: fix DCC clear */
+ if (rctx->chip_class >= GFX9)
+ continue;
+
if (rctx->screen->debug_flags & DBG_NO_DCC_CLEAR)
continue;
vi_dcc_clear_level(rctx, tex, 0, reset_value);
- if (clear_words_needed)
- tex->dirty_level_mask |= 1 << fb->cbufs[i]->u.tex.level;
+ unsigned level_bit = 1 << fb->cbufs[i]->u.tex.level;
+ if (clear_words_needed) {
+ bool need_compressed_update = !tex->dirty_level_mask;
+
+ tex->dirty_level_mask |= level_bit;
+
+ if (need_compressed_update)
+ p_atomic_inc(&rctx->screen->compressed_colortex_counter);
+ }
tex->separate_dcc_dirty = true;
} else {
/* 128-bit formats are unusupported */
continue;
}
- /* RB+ doesn't work with CMASK fast clear. */
- if (rctx->screen->rbplus_allowed)
+ /* RB+ doesn't work with CMASK fast clear on Stoney. */
+ if (rctx->family == CHIP_STONEY)
continue;
/* ensure CMASK is enabled */
tex->cmask.offset, tex->cmask.size, 0,
R600_COHERENCY_CB_META);
+ bool need_compressed_update = !tex->dirty_level_mask;
+
tex->dirty_level_mask |= 1 << fb->cbufs[i]->u.tex.level;
+
+ if (need_compressed_update)
+ p_atomic_inc(&rctx->screen->compressed_colortex_counter);
}
/* We can change the micro tile mode before a full clear. */