struct etna_resource *rsc)
{
struct etna_screen *screen = etna_screen(pscreen);
- size_t rt_ts_size, ts_layer_stride, pixels;
+ size_t rt_ts_size, ts_layer_stride;
+ size_t ts_bits_per_tile, bytes_per_tile;
+ uint8_t ts_mode = TS_MODE_128B; /* only used by halti5 */
+ int8_t ts_compress_fmt;
assert(!rsc->ts_bo);
- /* TS only for level 0 -- XXX is this formula correct? */
- pixels = rsc->levels[0].layer_stride / util_format_get_blocksize(rsc->base.format);
- ts_layer_stride = align(pixels * screen->specs.bits_per_tile / 0x80,
+ /* pre-v4 compression is largely useless, so disable it when not wanted for MSAA
+ * v4 compression can be enabled everywhere without any known drawback,
+ * except that in-place resolve must go through a slower path
+ */
+ ts_compress_fmt = (screen->specs.v4_compression || rsc->base.nr_samples > 1) ?
+ translate_ts_format(rsc->base.format) : -1;
+
+ if (screen->specs.halti >= 5) {
+ /* enable 256B ts mode with compression, as it improves performance
+ * the size of the resource might also determine if we want to use it or not
+ */
+ if (ts_compress_fmt >= 0)
+ ts_mode = TS_MODE_256B;
+
+ ts_bits_per_tile = 4;
+ bytes_per_tile = ts_mode == TS_MODE_256B ? 256 : 128;
+ } else {
+ ts_bits_per_tile = screen->specs.bits_per_tile;
+ bytes_per_tile = 64;
+ }
+
+ ts_layer_stride = align(DIV_ROUND_UP(rsc->levels[0].layer_stride,
+ bytes_per_tile * 8 / ts_bits_per_tile),
0x100 * screen->specs.pixel_pipes);
rt_ts_size = ts_layer_stride * rsc->base.array_size;
if (rt_ts_size == 0)
rsc->levels[0].ts_offset = 0;
rsc->levels[0].ts_layer_stride = ts_layer_stride;
rsc->levels[0].ts_size = rt_ts_size;
-
- /* It is important to initialize the TS, as random pattern
- * can result in crashes. Do this on the CPU as this only happens once
- * per surface anyway and it's a small area, so it may not be worth
- * queuing this to the GPU. */
- void *ts_map = etna_bo_map(rt_ts);
- memset(ts_map, screen->specs.ts_clear_value, rt_ts_size);
+ rsc->levels[0].ts_mode = ts_mode;
+ rsc->levels[0].ts_compress_fmt = ts_compress_fmt;
return true;
}
-static boolean
+static bool
etna_screen_can_create_resource(struct pipe_screen *pscreen,
const struct pipe_resource *templat)
{
mip->width = width;
mip->height = height;
+ mip->depth = depth;
mip->padded_width = align(width * msaa_xscale, paddingX);
mip->padded_height = align(height * msaa_yscale, paddingY);
mip->stride = util_format_get_stride(prsc->format, mip->padded_width);
paddingY = 1;
}
- if (!screen->specs.use_blt && templat->target != PIPE_BUFFER)
- etna_adjust_rs_align(screen->specs.pixel_pipes, NULL, &paddingY);
+ if (!screen->specs.use_blt && templat->target != PIPE_BUFFER && layout == ETNA_LAYOUT_LINEAR)
+ paddingY = align(paddingY, ETNA_RS_HEIGHT_MASK + 1);
if (templat->bind & PIPE_BIND_SCANOUT && screen->ro->kms_fd >= 0) {
struct pipe_resource scanout_templat = *templat;
struct winsys_handle handle;
/* pad scanout buffer size to be compatible with the RS */
- if (!screen->specs.use_blt && modifier == DRM_FORMAT_MOD_LINEAR)
- etna_adjust_rs_align(screen->specs.pixel_pipes, &paddingX, &paddingY);
+ if (!screen->specs.use_blt && modifier == DRM_FORMAT_MOD_LINEAR) {
+ paddingX = align(paddingX, ETNA_RS_WIDTH_MASK + 1);
+ paddingY = align(paddingY, ETNA_RS_HEIGHT_MASK + 1);
+ }
scanout_templat.width0 = align(scanout_templat.width0, paddingX);
scanout_templat.height0 = align(scanout_templat.height0, paddingY);
level->width = tmpl->width0;
level->height = tmpl->height0;
+ level->depth = tmpl->depth0;
+ level->offset = handle->offset;
/* Determine padding of the imported resource. */
unsigned paddingX = 0, paddingY = 0;
is_rs_align(screen, tmpl),
&paddingX, &paddingY, &rsc->halign);
- if (!screen->specs.use_blt)
- etna_adjust_rs_align(screen->specs.pixel_pipes, NULL, &paddingY);
+ if (!screen->specs.use_blt && rsc->layout == ETNA_LAYOUT_LINEAR)
+ paddingY = align(paddingY, ETNA_RS_HEIGHT_MASK + 1);
level->padded_width = align(level->width, paddingX);
level->padded_height = align(level->height, paddingY);
return NULL;
}
-static boolean
+static bool
etna_resource_get_handle(struct pipe_screen *pscreen,
struct pipe_context *pctx,
struct pipe_resource *prsc,
rsc = etna_resource(rsc->external);
handle->stride = rsc->levels[0].stride;
+ handle->offset = rsc->levels[0].offset;
handle->modifier = layout_to_modifier(rsc->layout);
if (handle->type == WINSYS_HANDLE_TYPE_SHARED) {
return etna_bo_get_name(rsc->bo, &handle->handle) == 0;
} else if (handle->type == WINSYS_HANDLE_TYPE_KMS) {
if (renderonly_get_handle(scanout, handle)) {
- return TRUE;
+ return true;
} else {
handle->handle = etna_bo_handle(rsc->bo);
- return TRUE;
+ return true;
}
} else if (handle->type == WINSYS_HANDLE_TYPE_FD) {
handle->handle = etna_bo_dmabuf(rsc->bo);
- return TRUE;
+ return true;
} else {
- return FALSE;
+ return false;
}
}