struct etna_resource *res = etna_resource(surf->base.texture);
struct blt_clear_op clr = {};
clr.dest.addr.bo = res->bo;
- clr.dest.addr.offset = surf->surf.offset;
+ clr.dest.addr.offset = surf->offset;
clr.dest.addr.flags = ETNA_RELOC_WRITE;
clr.dest.bpp = util_format_get_blocksize(surf->base.format);
- clr.dest.stride = surf->surf.stride;
+ clr.dest.stride = surf->level->stride;
clr.dest.tiling = res->layout;
- if (surf->surf.ts_size) {
+ if (surf->level->ts_size) {
clr.dest.use_ts = 1;
clr.dest.ts_addr.bo = res->ts_bo;
- clr.dest.ts_addr.offset = surf->surf.ts_offset;
+ clr.dest.ts_addr.offset = surf->ts_offset;
clr.dest.ts_addr.flags = ETNA_RELOC_WRITE;
clr.dest.ts_clear_value[0] = new_clear_value;
clr.dest.ts_clear_value[1] = new_clear_value >> 32;
clr.clear_bits[1] = 0xffffffff;
clr.rect_x = 0; /* What about scissors? */
clr.rect_y = 0;
- clr.rect_w = surf->surf.width * msaa_xscale;
- clr.rect_h = surf->surf.height * msaa_yscale;
+ clr.rect_w = surf->level->width * msaa_xscale;
+ clr.rect_h = surf->level->height * msaa_yscale;
emit_blt_clearimage(ctx->stream, &clr);
/* This made the TS valid */
- if (surf->surf.ts_size) {
+ if (surf->level->ts_size) {
ctx->framebuffer.TS_COLOR_CLEAR_VALUE = new_clear_value;
ctx->framebuffer.TS_COLOR_CLEAR_VALUE_EXT = new_clear_value >> 32;
struct etna_resource *res = etna_resource(surf->base.texture);
struct blt_clear_op clr = {};
clr.dest.addr.bo = res->bo;
- clr.dest.addr.offset = surf->surf.offset;
+ clr.dest.addr.offset = surf->offset;
clr.dest.addr.flags = ETNA_RELOC_WRITE;
clr.dest.bpp = util_format_get_blocksize(surf->base.format);
- clr.dest.stride = surf->surf.stride;
+ clr.dest.stride = surf->level->stride;
clr.dest.tiling = res->layout;
- if (surf->surf.ts_size) {
+ if (surf->level->ts_size) {
clr.dest.use_ts = 1;
clr.dest.ts_addr.bo = res->ts_bo;
- clr.dest.ts_addr.offset = surf->surf.ts_offset;
+ clr.dest.ts_addr.offset = surf->ts_offset;
clr.dest.ts_addr.flags = ETNA_RELOC_WRITE;
clr.dest.ts_clear_value[0] = surf->level->clear_value;
clr.dest.ts_clear_value[1] = surf->level->clear_value;
clr.clear_bits[1] = new_clear_bits;
clr.rect_x = 0; /* What about scissors? */
clr.rect_y = 0;
- clr.rect_w = surf->surf.width * msaa_xscale;
- clr.rect_h = surf->surf.height * msaa_yscale;
+ clr.rect_w = surf->level->width * msaa_xscale;
+ clr.rect_h = surf->level->height * msaa_yscale;
emit_blt_clearimage(ctx->stream, &clr);
/* This made the TS valid */
- if (surf->surf.ts_size) {
+ if (surf->level->ts_size) {
ctx->framebuffer.TS_DEPTH_CLEAR_VALUE = surf->level->clear_value;
surf->level->ts_valid = true;
ctx->dirty |= ETNA_DIRTY_TS | ETNA_DIRTY_DERIVE_TS;
}
/* use tiled clear if width is multiple of 16 */
- bool tiled_clear = (surf->surf.padded_width & ETNA_RS_WIDTH_MASK) == 0 &&
- (surf->surf.padded_height & ETNA_RS_HEIGHT_MASK) == 0;
+ bool tiled_clear = (surf->level->padded_width & ETNA_RS_WIDTH_MASK) == 0 &&
+ (surf->level->padded_height & ETNA_RS_HEIGHT_MASK) == 0;
etna_compile_rs_state( ctx, &surf->clear_command, &(struct rs_state) {
.source_format = format,
.dest_format = format,
.dest = dst->bo,
- .dest_offset = surf->surf.offset,
- .dest_stride = surf->surf.stride,
- .dest_padded_height = surf->surf.padded_height,
+ .dest_offset = surf->offset,
+ .dest_stride = surf->level->stride,
+ .dest_padded_height = surf->level->padded_height,
.dest_tiling = tiled_clear ? dst->layout : ETNA_LAYOUT_LINEAR,
.dither = {0xffffffff, 0xffffffff},
- .width = surf->surf.padded_width, /* These must be padded to 16x4 if !LINEAR, otherwise RS will hang */
- .height = surf->surf.padded_height,
+ .width = surf->level->padded_width, /* These must be padded to 16x4 if !LINEAR, otherwise RS will hang */
+ .height = surf->level->padded_height,
.clear_value = {clear_value, clear_value >> 32, clear_value, clear_value >> 32},
.clear_mode = VIVS_RS_CLEAR_CONTROL_MODE_ENABLED1,
.clear_bits = 0xffff
struct etna_surface *surf = etna_surface(dst);
uint64_t new_clear_value = etna_clear_blit_pack_rgba(surf->base.format, color);
- if (surf->surf.ts_size) { /* TS: use precompiled clear command */
+ if (surf->level->ts_size) { /* TS: use precompiled clear command */
ctx->framebuffer.TS_COLOR_CLEAR_VALUE = new_clear_value;
ctx->framebuffer.TS_COLOR_CLEAR_VALUE_EXT = new_clear_value >> 32;
if (VIV_FEATURE(ctx->screen, chipMinorFeatures1, AUTO_DISABLE)) {
/* Set number of color tiles to be filled */
etna_set_state(ctx->stream, VIVS_TS_COLOR_AUTO_DISABLE_COUNT,
- surf->surf.padded_width * surf->surf.padded_height / 16);
+ surf->level->padded_width * surf->level->padded_height / 16);
ctx->framebuffer.TS_MEM_CONFIG |= VIVS_TS_MEM_CONFIG_COLOR_AUTO_DISABLE;
}
* We may be better off recording the pending clear operation,
* delaying the actual clear to the first use. This way, we can merge
* consecutive clears together. */
- if (surf->surf.ts_size) { /* TS: use precompiled clear command */
+ if (surf->level->ts_size) { /* TS: use precompiled clear command */
/* Set new clear depth value */
ctx->framebuffer.TS_DEPTH_CLEAR_VALUE = new_clear_value;
if (VIV_FEATURE(ctx->screen, chipMinorFeatures1, AUTO_DISABLE)) {
/* Set number of depth tiles to be filled */
etna_set_state(ctx->stream, VIVS_TS_DEPTH_AUTO_DISABLE_COUNT,
- surf->surf.padded_width * surf->surf.padded_height / 16);
+ surf->level->padded_width * surf->level->padded_height / 16);
ctx->framebuffer.TS_MEM_CONFIG |= VIVS_TS_MEM_CONFIG_DEPTH_AUTO_DISABLE;
}
bool need_ts_flush = false;
if ((buffers & PIPE_CLEAR_COLOR) && ctx->framebuffer_s.nr_cbufs) {
struct etna_surface *surf = etna_surface(ctx->framebuffer_s.cbufs[0]);
- if (surf->surf.ts_size)
+
+ if (surf->level->ts_size)
need_ts_flush = true;
}
if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && ctx->framebuffer_s.zsbuf != NULL) {
struct etna_surface *surf = etna_surface(ctx->framebuffer_s.zsbuf);
- if (surf->surf.ts_size)
+ if (surf->level->ts_size)
need_ts_flush = true;
}
* VIVS_PE_COLOR_FORMAT_OVERWRITE comes from blend_state
* but only if we set the bits above. */
/* merged with depth_stencil_alpha */
- if ((cbuf->surf.offset & 63) ||
- (((cbuf->surf.stride * 4) & 63) && cbuf->surf.height > 4)) {
+ if ((cbuf->offset & 63) ||
+ (((cbuf->level->stride * 4) & 63) && cbuf->level->height > 4)) {
/* XXX Must make temporary surface here.
* Need the same mechanism on gc2000 when we want to do mipmap
* generation by
* rendering to levels > 1 due to multitiled / tiled conversion. */
BUG("Alignment error, trying to render to offset %08x with tile "
"stride %i",
- cbuf->surf.offset, cbuf->surf.stride * 4);
+ cbuf->offset, cbuf->level->stride * 4);
}
if (screen->specs.halti >= 0 && screen->model != 0x880) {
cs->PE_COLOR_ADDR.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
}
- cs->PE_COLOR_STRIDE = cbuf->surf.stride;
+ cs->PE_COLOR_STRIDE = cbuf->level->stride;
- if (cbuf->surf.ts_size) {
+ if (cbuf->level->ts_size) {
cs->TS_COLOR_CLEAR_VALUE = cbuf->level->clear_value;
cs->TS_COLOR_CLEAR_VALUE_EXT = cbuf->level->clear_value >> 32;
cs->PE_DEPTH_ADDR.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
}
- cs->PE_DEPTH_STRIDE = zsbuf->surf.stride;
+ cs->PE_DEPTH_STRIDE = zsbuf->level->stride;
cs->PE_HDEPTH_CONTROL = VIVS_PE_HDEPTH_CONTROL_FORMAT_DISABLED;
cs->PE_DEPTH_NORMALIZE = fui(exp2f(depth_bits) - 1.0f);
- if (zsbuf->surf.ts_size) {
+ if (zsbuf->level->ts_size) {
cs->TS_DEPTH_CLEAR_VALUE = zsbuf->level->clear_value;
cs->TS_DEPTH_STATUS_BASE = zsbuf->ts_reloc;
unsigned layer = templat->u.tex.first_layer;
unsigned level = templat->u.tex.level;
struct etna_resource *rsc = etna_render_handle_incompatible(pctx, prsc, level);
+ struct etna_resource_level *lev = &rsc->levels[level];
struct etna_surface *surf = CALLOC_STRUCT(etna_surface);
if (!surf)
surf->base.height = rsc->levels[level].height;
surf->base.writable = templat->writable; /* what is this for anyway */
surf->base.u = templat->u;
-
- surf->level = &rsc->levels[level]; /* Keep pointer to actual level to set
- * clear color on underlying resource
- * instead of surface */
- surf->surf = rsc->levels [level]; /* Make copy of level to narrow down
- * address to layer */
+ surf->level = lev;
/* XXX we don't really need a copy but it's convenient */
- surf->surf.offset += layer * surf->surf.layer_stride;
-
- struct etna_resource_level *lev = &rsc->levels[level];
+ surf->offset = lev->offset + layer * lev->layer_stride;
/* Setup template relocations for this surface */
for (unsigned pipe = 0; pipe < screen->specs.pixel_pipes; ++pipe) {
surf->reloc[pipe].bo = rsc->bo;
- surf->reloc[pipe].offset = surf->surf.offset;
+ surf->reloc[pipe].offset = surf->offset;
surf->reloc[pipe].flags = 0;
}
* point halfway the image vertically.
*/
if (rsc->layout & ETNA_LAYOUT_BIT_MULTI)
- surf->reloc[1].offset = surf->surf.offset + lev->stride * lev->padded_height / 2;
+ surf->reloc[1].offset = surf->offset + lev->stride * lev->padded_height / 2;
- if (surf->surf.ts_size) {
- unsigned int layer_offset = layer * surf->surf.ts_layer_stride;
- assert(layer_offset < surf->surf.ts_size);
+ if (surf->level->ts_size) {
+ unsigned int layer_offset = layer * lev->ts_layer_stride;
+ assert(layer_offset < surf->level->ts_size);
- surf->surf.ts_offset += layer_offset;
- surf->surf.ts_valid = false;
+ surf->ts_offset = surf->level->ts_offset + layer_offset;
surf->ts_reloc.bo = rsc->ts_bo;
- surf->ts_reloc.offset = surf->surf.ts_offset;
+ surf->ts_reloc.offset = surf->ts_offset;
surf->ts_reloc.flags = 0;
if (!screen->specs.use_blt) {
.source_format = RS_FORMAT_A8R8G8B8,
.dest_format = RS_FORMAT_A8R8G8B8,
.dest = ts_bo,
- .dest_offset = surf->surf.ts_offset,
+ .dest_offset = surf->ts_offset,
.dest_stride = 0x40,
.dest_tiling = ETNA_LAYOUT_TILED,
.dither = {0xffffffff, 0xffffffff},
struct etna_surface {
struct pipe_surface base;
- struct etna_resource_level surf;
struct compiled_rs_state clear_command;
/* Keep pointer to resource level, for fast clear */
struct etna_resource_level *level;
struct etna_reloc reloc[ETNA_MAX_PIXELPIPES];
struct etna_reloc ts_reloc;
+ uint32_t offset; /* pre-calculated level + layer offset */
+ uint32_t ts_offset; /* pre-calculated level + layer TS offset */
/* keep pointer to original resource (for when a render compatible resource is used) */
struct pipe_resource *prsc;
};