diff options
author | Lucas Stach <l.stach@pengutronix.de> | 2014-08-15 17:14:59 +0200 |
---|---|---|
committer | Lucas Stach <l.stach@pengutronix.de> | 2014-08-15 17:14:59 +0200 |
commit | f6a55df9d5bd44a7702cb8c1b302077e0eec238b (patch) | |
tree | fdd6f6eac2a3b141e6946036f26c0ac809785bfc | |
parent | 36962c854c61e2731b5155c707b2f99f7f076923 (diff) | |
download | mesa-master.tar.gz mesa-master.tar.xz |
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.c | 85 | ||||
-rw-r--r-- | src/gallium/drivers/etna/etna_pipe.h | 18 |
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, ©_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, ©_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 |