summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLucas Stach <l.stach@pengutronix.de>2014-08-15 17:14:59 +0200
committerLucas Stach <l.stach@pengutronix.de>2014-08-15 17:14:59 +0200
commitf6a55df9d5bd44a7702cb8c1b302077e0eec238b (patch)
treefdd6f6eac2a3b141e6946036f26c0ac809785bfc
parent36962c854c61e2731b5155c707b2f99f7f076923 (diff)
downloadmesa-master.tar.gz
mesa-master.tar.xz
etna: dehackify resolve pathHEADmaster
Makes the RS resolve a lot less painful. Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
-rw-r--r--src/gallium/drivers/etna/etna_pipe.c85
-rw-r--r--src/gallium/drivers/etna/etna_pipe.h18
2 files changed, 64 insertions, 39 deletions
diff --git a/src/gallium/drivers/etna/etna_pipe.c b/src/gallium/drivers/etna/etna_pipe.c
index eb226797d0..d3b9a25a86 100644
--- a/src/gallium/drivers/etna/etna_pipe.c
+++ b/src/gallium/drivers/etna/etna_pipe.c
@@ -875,25 +875,22 @@ static void do_resolve(struct etna_pipe_context *context)
etna_set_state(context->ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR);
etna_stall(context->ctx, SYNC_RECIPIENT_RA, SYNC_RECIPIENT_PE);
-#if 0
/* Set up color TS to source surface before blit, if needed */
uint32_t ts_mem_config = 0;
if(res->levels[0].ts_size) {
- debug_printf("ts_size\n");
etna_set_state_multi(ectx->ctx, VIVS_TS_MEM_CONFIG, 4, (uint32_t[]) {
ectx->gpu3d.TS_MEM_CONFIG = VIVS_TS_MEM_CONFIG_COLOR_FAST_CLEAR | ts_mem_config,
ectx->gpu3d.TS_COLOR_STATUS_BASE = etna_bo_gpu_address(res->ts_bo) + res->levels[0].ts_offset,
ectx->gpu3d.TS_COLOR_SURFACE_BASE = etna_bo_gpu_address(res->bo) + res->levels[0].offset,
ectx->gpu3d.TS_COLOR_CLEAR_VALUE = res->levels[0].clear_value
});
+ ectx->dirty_bits |= ETNA_STATE_TS;
}
- ectx->dirty_bits |= ETNA_STATE_TS;
-#endif
shadow_size = util_format_get_nblocksy(cbuf->base.format, cbuf->level->padded_height) * util_format_get_stride(cbuf->base.format, cbuf->level->padded_width);
struct compiled_rs_state copy_to_screen;
etna_compile_rs_state(context->ctx, &copy_to_screen, &(struct rs_state){
- .source_format = translate_rt_format(cbuf->shadow_format, false),
+ .source_format = translate_rt_format(cbuf->base.format, false),
.source_tiling = cbuf->shadow_layout,
.source_addr[0] = etna_bo_gpu_address(cbuf->shadow),
.source_addr[1] = etna_bo_gpu_address(cbuf->shadow) + shadow_size /2,
@@ -911,6 +908,9 @@ static void do_resolve(struct etna_pipe_context *context)
.height = cbuf->level->padded_height
});
etna_submit_rs_state(context->ctx, &copy_to_screen);
+
+ etna_bo_del(etna_screen(ectx->base.screen)->dev, cbuf->shadow, NULL);
+ cbuf->shadow = NULL;
}
}
static void etna_pipe_draw_vbo(struct pipe_context *pipe,
@@ -1072,23 +1072,24 @@ static void etna_pipe_set_framebuffer_state(struct pipe_context *pipe,
struct etna_pipe_context *priv = etna_pipe_context(pipe);
struct etna_screen *screen = etna_screen(pipe->screen);
struct compiled_framebuffer_state *cs = &priv->framebuffer;
+ struct etna_resource *res;
+ int rt_size;
int nr_samples_color = -1;
int nr_samples_depth = -1;
- int shadow_size;
+ uint32_t pipe_addr[2];
/* Set up TS as well. Warning: this state is used by both the RS and PE */
uint32_t ts_mem_config = 0;
if(sv->nr_cbufs > 0) /* at least one color buffer? */
{
struct etna_surface *cbuf = etna_surface(sv->cbufs[0]);
- bool color_supertiled = (cbuf->layout & 2)!=0;
- assert(cbuf->layout & 1); /* Cannot render to linear surfaces */
pipe_surface_reference(&cs->cbuf, &cbuf->base);
- cs->PE_COLOR_FORMAT =
- VIVS_PE_COLOR_FORMAT_FORMAT(translate_rt_format(cbuf->base.format, false)) |
- (color_supertiled ? VIVS_PE_COLOR_FORMAT_SUPER_TILED : 0);
- /* XXX VIVS_PE_COLOR_FORMAT_OVERWRITE and the rest comes from blend_state / depth_stencil_alpha */
- /* merged with depth_stencil_alpha */
+ res = etna_resource(cbuf->base.texture);
+ rt_size = cbuf->surf.size;
+
+ pipe_addr[0] = etna_bo_gpu_address(res->bo) + cbuf->surf.offset;
+ pipe_addr[1] = etna_bo_gpu_address(res->bo) + cbuf->surf.offset + rt_size / 2;
+
if((cbuf->surf.offset & 63) || (((cbuf->surf.stride*4) & 63) && cbuf->surf.height > 4))
{
/* XXX Must make temporary surface here.
@@ -1099,29 +1100,41 @@ static void etna_pipe_set_framebuffer_state(struct pipe_context *pipe,
cbuf->surf.offset, cbuf->surf.stride*4);
}
- struct etna_resource *res = etna_resource(cbuf->base.texture);
- if (priv->ctx->conn->chip.pixel_pipes == 1)
- {
- cs->PE_COLOR_ADDR = etna_get_level_pipe_addr(res, 0, 0);
+ /* those are the cases where we need a shadow RT */
+ if ((!(cbuf->layout & ETNA_LAYOUT_ANY_TILING)) ||
+ (priv->ctx->conn->chip.pixel_pipes > 1 &&
+ !(cbuf->layout & ETNA_LAYOUT_MULTIPIPE)) ||
+ translate_rb_format_swap(cbuf->base.format)) {
+ cbuf->shadow_layout = cbuf->layout;
+
+ /* can not render to linear, use tiled instead */
+ /* XXX: maybe even use supertiling here? */
+ if (!(cbuf->shadow_layout & ETNA_LAYOUT_ANY_TILING))
+ cbuf->shadow_layout = ETNA_LAYOUT_TILED;
+
+ /* upgrade format to multipipe if necessary */
+ if (priv->ctx->conn->chip.pixel_pipes > 1)
+ cbuf->shadow_layout |= ETNA_LAYOUT_MULTIPIPE;
+
+ cbuf->shadow = etna_bo_new(screen->dev, rt_size,
+ DRM_ETNA_GEM_TYPE_RT);
+
+ pipe_addr[0] = etna_bo_gpu_address(cbuf->shadow);
+ pipe_addr[1] = etna_bo_gpu_address(cbuf->shadow) + rt_size / 2;
}
- else if (priv->ctx->conn->chip.pixel_pipes == 2)
- {
- if (color_supertiled) {
- cs->PE_PIPE_COLOR_ADDR[0] = etna_get_level_pipe_addr(res, 0, 0);
- cs->PE_PIPE_COLOR_ADDR[1] = etna_get_level_pipe_addr(res, 0, 1);
- cs->TS_COLOR_SURFACE_BASE = etna_get_level_pipe_addr(res, 0, 0);
- } else {
- /* need a shadow buffer to resolve MULTI_TILED */
- debug_printf("set shadow RT\n");
- shadow_size = util_format_get_nblocksy(cbuf->base.format, cbuf->level->padded_height) * util_format_get_stride(cbuf->base.format, cbuf->level->padded_width);
- cbuf->shadow = etna_bo_new(screen->dev, shadow_size, DRM_ETNA_GEM_TYPE_RT);
- cbuf->shadow_layout = ETNA_LAYOUT_MULTI_TILED;
- cbuf->shadow_format = cbuf->base.format;
-
- cs->PE_PIPE_COLOR_ADDR[0] = etna_bo_gpu_address(cbuf->shadow);
- cs->PE_PIPE_COLOR_ADDR[1] = etna_bo_gpu_address(cbuf->shadow) + shadow_size / 2;
- cs->TS_COLOR_SURFACE_BASE = etna_bo_gpu_address(cbuf->shadow);
- }
+
+ cs->PE_COLOR_FORMAT =
+ VIVS_PE_COLOR_FORMAT_FORMAT(translate_rt_format(cbuf->base.format, false)) |
+ ((cbuf->layout & ETNA_LAYOUT_SUPER_TILED) ? VIVS_PE_COLOR_FORMAT_SUPER_TILED : 0);
+ /* XXX VIVS_PE_COLOR_FORMAT_OVERWRITE and the rest comes from blend_state / depth_stencil_alpha */
+ /* merged with depth_stencil_alpha */
+
+ if (priv->ctx->conn->chip.pixel_pipes == 1) {
+ cs->PE_COLOR_ADDR = pipe_addr[0];
+ } else if (priv->ctx->conn->chip.pixel_pipes == 2) {
+ cs->PE_PIPE_COLOR_ADDR[0] = pipe_addr[0];
+ cs->PE_PIPE_COLOR_ADDR[1] = pipe_addr[1];
+ cs->TS_COLOR_SURFACE_BASE = pipe_addr[0];
}
cs->PE_COLOR_STRIDE = cbuf->surf.stride;
if(cbuf->surf.ts_size)
@@ -1144,7 +1157,7 @@ static void etna_pipe_set_framebuffer_state(struct pipe_context *pipe,
{
struct etna_surface *zsbuf = etna_surface(sv->zsbuf);
pipe_surface_reference(&cs->zsbuf, &zsbuf->base);
- assert(zsbuf->layout & 1); /* Cannot render to linear surfaces */
+ assert(!(zsbuf->layout & ETNA_LAYOUT_LINEAR)); /* Cannot render to linear surfaces */
uint32_t depth_format = translate_depth_format(zsbuf->base.format, false);
unsigned depth_bits = depth_format == VIVS_PE_DEPTH_CONFIG_DEPTH_FORMAT_D16 ? 16 : 24;
bool depth_supertiled = (zsbuf->layout & 2)!=0;
diff --git a/src/gallium/drivers/etna/etna_pipe.h b/src/gallium/drivers/etna/etna_pipe.h
index ed5f744bfa..3719a5669a 100644
--- a/src/gallium/drivers/etna/etna_pipe.h
+++ b/src/gallium/drivers/etna/etna_pipe.h
@@ -73,13 +73,27 @@ struct etna_resource_level
uint32_t clear_value; /* clear value of resource level (mainly for TS) */
};
+/* basic tile flags */
+#define ETNA_LAYOUT_LINEAR 0x0
+#define ETNA_LAYOUT_TILED 0x1
+#define ETNA_LAYOUT_SUPER_TILED 0x2
+#define ETNA_LAYOUT_MULTIPIPE 0x4
+
+/* convenience combined tile flags */
+#define ETNA_LAYOUT_ANY_TILING \
+ (ETNA_LAYOUT_TILED | ETNA_LAYOUT_SUPER_TILED)
+#define ETNA_LAYOUT_MULTI_SUPER_TILED \
+ (ETNA_LAYOUT_SUPER_TILED | ETNA_LAYOUT_MULTIPIPE)
+#define ETNA_LAYOUT_MULTI_TILED \
+ (ETNA_LAYOUT_TILED | ETNA_LAYOUT_MULTIPIPE)
+
struct etna_resource
{
struct pipe_resource base;
/* only lod 0 used for non-texture buffers */
/* Layout for surface (tiled, multitiled, split tiled, ...) */
- enum etna_surface_layout layout;
+ uint32_t layout;
/* Horizontal alignment for texture unit (TEXTURE_HALIGN_*) */
unsigned halign;
struct etna_bo *bo; /* Surface video memory */
@@ -99,10 +113,8 @@ struct etna_surface
/* Keep pointer to resource level, for fast clear */
struct etna_resource_level *level;
- bool needs_resolve;
struct etna_bo *shadow;
enum etna_surface_layout shadow_layout;
- enum pipe_format shadow_format;
};
struct etna_sampler_view