#include "state_tracker/drm_driver.h"
#include "amd/common/sid.h"
-static void r600_texture_discard_cmask(struct si_screen *sscreen,
- struct r600_texture *rtex);
static enum radeon_surf_mode
r600_choose_tiling(struct si_screen *sscreen,
const struct pipe_resource *templ);
src_box->height, src_box->depth))
return false;
- r600_texture_discard_cmask(rctx->screen, rdst);
+ si_texture_discard_cmask(rctx->screen, rdst);
}
/* All requirements are met. Prepare textures for SDMA. */
bpe = 4; /* stencil is allocated separately on evergreen */
} else {
bpe = util_format_get_blocksize(ptex->format);
- assert(util_is_power_of_two(bpe));
+ assert(util_is_power_of_two_or_zero(bpe));
}
if (!is_flushed_depth && is_depth) {
return r;
}
+ unsigned pitch = pitch_in_bytes_override / bpe;
+
if (sscreen->info.chip_class >= GFX9) {
- assert(!pitch_in_bytes_override ||
- pitch_in_bytes_override == surface->u.gfx9.surf_pitch * bpe);
+ if (pitch) {
+ surface->u.gfx9.surf_pitch = pitch;
+ surface->u.gfx9.surf_slice_size =
+ (uint64_t)pitch * surface->u.gfx9.surf_height * bpe;
+ }
surface->u.gfx9.surf_offset = offset;
} else {
+ if (pitch) {
+ surface->u.legacy.level[0].nblk_x = pitch;
+ surface->u.legacy.level[0].slice_size_dw =
+ ((uint64_t)pitch * surface->u.legacy.level[0].nblk_y * bpe) / 4;
+ }
if (offset) {
for (i = 0; i < ARRAY_SIZE(surface->u.legacy.level); ++i)
surface->u.legacy.level[i].offset += offset;
}
}
-static void r600_eliminate_fast_color_clear(struct r600_common_context *rctx,
- struct r600_texture *rtex)
+void si_eliminate_fast_color_clear(struct r600_common_context *rctx,
+ struct r600_texture *rtex)
{
struct si_screen *sscreen = rctx->screen;
struct pipe_context *ctx = &rctx->b;
if (ctx == sscreen->aux_context)
mtx_lock(&sscreen->aux_context_lock);
+ unsigned n = rctx->num_decompress_calls;
ctx->flush_resource(ctx, &rtex->resource.b.b);
- ctx->flush(ctx, NULL, 0);
+
+ /* Flush only if any fast clear elimination took place. */
+ if (n != rctx->num_decompress_calls)
+ ctx->flush(ctx, NULL, 0);
if (ctx == sscreen->aux_context)
mtx_unlock(&sscreen->aux_context_lock);
}
-static void r600_texture_discard_cmask(struct si_screen *sscreen,
- struct r600_texture *rtex)
+void si_texture_discard_cmask(struct si_screen *sscreen,
+ struct r600_texture *rtex)
{
if (!rtex->cmask.size)
return;
mtx_lock(&sscreen->aux_context_lock);
/* Decompress DCC. */
- rctx->decompress_dcc(&rctx->b, rtex);
+ si_decompress_dcc(&rctx->b, rtex);
rctx->b.flush(&rctx->b, NULL, 0);
if (&rctx->b == sscreen->aux_context)
u_box_3d(0, 0, 0,
u_minify(templ.width0, i), u_minify(templ.height0, i),
- util_max_layer(&templ, i) + 1, &box);
+ util_num_layers(&templ, i), &box);
rctx->dma_copy(&rctx->b, &new_tex->resource.b.b, i, 0, 0, 0,
&rtex->resource.b.b, i, &box);
}
if (new_bind_flag == PIPE_BIND_LINEAR) {
- r600_texture_discard_cmask(rctx->screen, rtex);
+ si_texture_discard_cmask(rctx->screen, rtex);
r600_texture_discard_dcc(rctx->screen, rtex);
}
PIPE_SWIZZLE_W
};
uint32_t desc[8], i;
- bool is_array = util_resource_is_array_texture(res);
+ bool is_array = util_texture_is_array(res->target);
/* DRM 2.x.x doesn't support this. */
if (sscreen->info.drm_major != 3)
if (sscreen->ws->buffer_is_suballocated(res->buf) ||
rtex->surface.tile_swizzle ||
(rtex->resource.flags & RADEON_FLAG_NO_INTERPROCESS_SHARING &&
+ sscreen->info.has_local_buffers &&
whandle->type != DRM_API_HANDLE_TYPE_KMS)) {
assert(!res->b.is_shared);
r600_reallocate_texture_inplace(rctx, rtex,
if (!(usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH) &&
(rtex->cmask.size || rtex->dcc_offset)) {
/* Eliminate fast clear (both CMASK and DCC) */
- r600_eliminate_fast_color_clear(rctx, rtex);
+ si_eliminate_fast_color_clear(rctx, rtex);
/* eliminate_fast_color_clear flushes the context */
flush = false;
* to be called.
*/
if (rtex->cmask.size)
- r600_texture_discard_cmask(sscreen, rtex);
+ si_texture_discard_cmask(sscreen, rtex);
}
/* Set metadata. */
slice_size = (uint64_t)rtex->surface.u.legacy.level[0].slice_size_dw * 4;
}
} else {
+ /* Buffer exports are for the OpenCL interop. */
/* Move a suballocated buffer into a non-suballocated allocation. */
- if (sscreen->ws->buffer_is_suballocated(res->buf)) {
+ if (sscreen->ws->buffer_is_suballocated(res->buf) ||
+ /* A DMABUF export always fails if the BO is local. */
+ (rtex->resource.flags & RADEON_FLAG_NO_INTERPROCESS_SHARING &&
+ sscreen->info.has_local_buffers)) {
assert(!res->b.is_shared);
/* Allocate a new buffer with PIPE_BIND_SHARED. */
if (sscreen->info.chip_class >= GFX9) {
out->alignment = rtex->surface.u.gfx9.fmask_alignment;
out->size = rtex->surface.u.gfx9.fmask_size;
+ out->tile_swizzle = rtex->surface.u.gfx9.fmask_tile_swizzle;
return;
}
out->slice_tile_max -= 1;
out->alignment = MAX2(256, base_align);
- out->size = (util_max_layer(&rtex->resource.b.b, 0) + 1) *
+ out->size = util_num_layers(&rtex->resource.b.b, 0) *
align(slice_bytes, base_align);
}
rtex->surface.htile_alignment = base_align;
rtex->surface.htile_size =
- (util_max_layer(&rtex->resource.b.b, 0) + 1) *
+ util_num_layers(&rtex->resource.b.b, 0) *
align(slice_bytes, base_align);
}
r600_texture_allocate_htile(sscreen, rtex);
}
} else {
- if (base->nr_samples > 1) {
- if (!buf) {
- r600_texture_allocate_fmask(sscreen, rtex);
- r600_texture_allocate_cmask(sscreen, rtex);
- rtex->cmask_buffer = &rtex->resource;
- }
+ if (base->nr_samples > 1 &&
+ !buf &&
+ !(sscreen->debug_flags & DBG(NO_FMASK))) {
+ r600_texture_allocate_fmask(sscreen, rtex);
+ r600_texture_allocate_cmask(sscreen, rtex);
+ rtex->cmask_buffer = &rtex->resource;
+
if (!rtex->fmask.size || !rtex->cmask.size) {
FREE(rtex);
return NULL;
fprintf(stderr, "VM start=0x%"PRIX64" end=0x%"PRIX64" | Texture %ix%ix%i, %i levels, %i samples, %s\n",
rtex->resource.gpu_address,
rtex->resource.gpu_address + rtex->resource.buf->size,
- base->width0, base->height0, util_max_layer(base, 0)+1, base->last_level+1,
+ base->width0, base->height0, util_num_layers(base, 0), base->last_level+1,
base->nr_samples ? base->nr_samples : 1, util_format_short_name(base->format));
}
* The result is that the kernel memory manager is never a bottleneck.
*/
if (rctx->num_alloc_tex_transfer_bytes > rctx->screen->info.gart_size / 4) {
- rctx->gfx.flush(rctx, PIPE_FLUSH_ASYNC, NULL);
+ si_flush_gfx_cs(rctx, PIPE_FLUSH_ASYNC, NULL);
rctx->num_alloc_tex_transfer_bytes = 0;
}
/* DCC channel type categories within which formats can be reinterpreted
* while keeping the same DCC encoding. The swizzle must also match. */
enum dcc_channel_type {
- dcc_channel_float32,
- dcc_channel_uint32,
- dcc_channel_sint32,
- dcc_channel_float16,
- dcc_channel_uint16,
- dcc_channel_sint16,
+ dcc_channel_float,
+ /* uint and sint can be merged if we never use TC-compatible DCC clear
+ * encoding with the clear value of 1. */
+ dcc_channel_uint,
+ dcc_channel_sint,
dcc_channel_uint_10_10_10_2,
- dcc_channel_uint8,
- dcc_channel_sint8,
dcc_channel_incompatible,
};
switch (desc->channel[i].size) {
case 32:
- if (desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT)
- return dcc_channel_float32;
- if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED)
- return dcc_channel_uint32;
- return dcc_channel_sint32;
case 16:
+ case 8:
if (desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT)
- return dcc_channel_float16;
+ return dcc_channel_float;
if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED)
- return dcc_channel_uint16;
- return dcc_channel_sint16;
+ return dcc_channel_uint;
+ return dcc_channel_sint;
case 10:
return dcc_channel_uint_10_10_10_2;
- case 8:
- if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED)
- return dcc_channel_uint8;
- return dcc_channel_sint8;
default:
return dcc_channel_incompatible;
}
if (vi_dcc_formats_are_incompatible(tex, level, view_format))
if (!si_texture_disable_dcc(rctx, (struct r600_texture*)tex))
- rctx->decompress_dcc(&rctx->b, rtex);
+ si_decompress_dcc(&rctx->b, rtex);
}
struct pipe_surface *si_create_surface_custom(struct pipe_context *pipe,
assert(tex->surface.num_dcc_levels);
assert(!tex->dcc_separate_buffer);
- r600_texture_discard_cmask(rctx->screen, tex);
+ si_texture_discard_cmask(rctx->screen, tex);
/* Get a DCC buffer. */
if (tex->last_dcc_separate_buffer) {