From: Vasily Khoruzhick Date: Sun, 7 Apr 2019 05:55:36 +0000 (-0700) Subject: lima: add support for depth/stencil fbo attachments and textures X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=fef2f10cc2ad298f179d5a5aa0a210fbea02d95f;p=mesa.git lima: add support for depth/stencil fbo attachments and textures Hardware supports writing back Z/S buffers and sampling from them, so add support for that. Signed-off-by: Vasily Khoruzhick Reviewed-by: Qiang Yu Tested-by: Icenowy Zheng --- diff --git a/src/gallium/drivers/lima/lima_context.c b/src/gallium/drivers/lima/lima_context.c index 35350ee71b8..9a373b96728 100644 --- a/src/gallium/drivers/lima/lima_context.c +++ b/src/gallium/drivers/lima/lima_context.c @@ -273,3 +273,15 @@ lima_need_flush(struct lima_context *ctx, struct lima_bo *bo, bool write) return lima_submit_has_bo(ctx->gp_submit, bo, write) || lima_submit_has_bo(ctx->pp_submit, bo, write); } + +bool +lima_is_scanout(struct lima_context *ctx) +{ + /* If there is no color buffer, it's an FBO */ + if (!ctx->framebuffer.base.nr_cbufs) + return false; + + return ctx->framebuffer.base.cbufs[0]->texture->bind & PIPE_BIND_DISPLAY_TARGET || + ctx->framebuffer.base.cbufs[0]->texture->bind & PIPE_BIND_SCANOUT || + ctx->framebuffer.base.cbufs[0]->texture->bind & PIPE_BIND_SHARED; +} diff --git a/src/gallium/drivers/lima/lima_context.h b/src/gallium/drivers/lima/lima_context.h index 469378a4a36..4bbe915bcdc 100644 --- a/src/gallium/drivers/lima/lima_context.h +++ b/src/gallium/drivers/lima/lima_context.h @@ -292,5 +292,6 @@ lima_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags); void lima_flush(struct lima_context *ctx); bool lima_need_flush(struct lima_context *ctx, struct lima_bo *bo, bool write); +bool lima_is_scanout(struct lima_context *ctx); #endif diff --git a/src/gallium/drivers/lima/lima_draw.c b/src/gallium/drivers/lima/lima_draw.c index 2cbcadae1b1..e0a1e181937 100644 --- a/src/gallium/drivers/lima/lima_draw.c +++ b/src/gallium/drivers/lima/lima_draw.c @@ -116,6 +116,10 @@ struct lima_render_state { uint32_t varyings_address; }; +#define LIMA_PIXEL_FORMAT_B8G8R8A8 0x03 +#define LIMA_PIXEL_FORMAT_Z16 0x0e +#define LIMA_PIXEL_FORMAT_Z24S8 0x0f + /* plbu commands */ #define PLBU_CMD_BEGIN(max) { \ int i = 0, max_n = max; \ @@ -211,6 +215,9 @@ lima_ctx_dirty(struct lima_context *ctx) static bool lima_fb_need_reload(struct lima_context *ctx) { + /* Depth buffer is always discarded */ + if (!ctx->framebuffer.base.nr_cbufs) + return false; if (ctx->damage.region) { /* for EGL_KHR_partial_update we just want to reload the * region not aligned to tile boundary */ @@ -670,8 +677,14 @@ lima_update_submit_bo(struct lima_context *ctx) else ctx->pp_stream.bo = NULL; - struct lima_resource *res = lima_resource(ctx->framebuffer.base.cbufs[0]->texture); - lima_submit_add_bo(ctx->pp_submit, res->bo, LIMA_SUBMIT_BO_WRITE); + if (ctx->framebuffer.base.nr_cbufs) { + struct lima_resource *res = lima_resource(ctx->framebuffer.base.cbufs[0]->texture); + lima_submit_add_bo(ctx->pp_submit, res->bo, LIMA_SUBMIT_BO_WRITE); + } + if (ctx->framebuffer.base.zsbuf) { + struct lima_resource *res = lima_resource(ctx->framebuffer.base.zsbuf->texture); + lima_submit_add_bo(ctx->pp_submit, res->bo, LIMA_SUBMIT_BO_WRITE); + } lima_submit_add_bo(ctx->pp_submit, ctx->plb[ctx->plb_index], LIMA_SUBMIT_BO_READ); lima_submit_add_bo(ctx->pp_submit, ctx->gp_tile_heap[ctx->plb_index], LIMA_SUBMIT_BO_READ); lima_submit_add_bo(ctx->pp_submit, screen->pp_buffer, LIMA_SUBMIT_BO_READ); @@ -688,7 +701,7 @@ lima_clear(struct pipe_context *pctx, unsigned buffers, lima_flush(ctx); /* no need to reload if cleared */ - if (buffers & PIPE_CLEAR_COLOR0) { + if (ctx->framebuffer.base.nr_cbufs && (buffers & PIPE_CLEAR_COLOR0)) { struct lima_surface *surf = lima_surface(ctx->framebuffer.base.cbufs[0]); surf->reload = false; } @@ -1421,13 +1434,47 @@ lima_finish_plbu_cmd(struct lima_context *ctx) } static void -lima_pack_pp_frame_reg(struct lima_context *ctx, uint32_t *frame_reg, - uint32_t *wb_reg) +lima_pack_wb_zsbuf_reg(struct lima_context *ctx, uint32_t *wb_reg, int wb_idx) { - struct lima_resource *res = lima_resource(ctx->framebuffer.base.cbufs[0]->texture); + struct lima_context_framebuffer *fb = &ctx->framebuffer; + struct lima_resource *res = lima_resource(fb->base.zsbuf->texture); + + uint32_t format; + + switch (fb->base.zsbuf->format) { + case PIPE_FORMAT_Z16_UNORM: + format = LIMA_PIXEL_FORMAT_Z16; + break; + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + case PIPE_FORMAT_Z24X8_UNORM: + default: + /* Assume Z24S8 */ + format = LIMA_PIXEL_FORMAT_Z24S8; + break; + } + + struct lima_pp_wb_reg *wb = (void *)wb_reg; + wb[wb_idx].type = 0x01; /* 1 for depth, stencil */ + wb[wb_idx].address = res->bo->va; + wb[wb_idx].pixel_format = format; + if (res->tiled) { + wb[wb_idx].pixel_layout = 0x2; + wb[wb_idx].pitch = fb->tiled_w; + } else { + wb[wb_idx].pixel_layout = 0x0; + wb[wb_idx].pitch = res->levels[0].stride / 8; + } + wb[wb_idx].mrt_bits = 0; +} + +static void +lima_pack_wb_cbuf_reg(struct lima_context *ctx, uint32_t *wb_reg, int wb_idx) +{ + struct lima_context_framebuffer *fb = &ctx->framebuffer; + struct lima_resource *res = lima_resource(fb->base.cbufs[0]->texture); bool swap_channels = false; - switch (ctx->framebuffer.base.cbufs[0]->format) { + switch (fb->base.cbufs[0]->format) { case PIPE_FORMAT_R8G8B8A8_UNORM: case PIPE_FORMAT_R8G8B8X8_UNORM: swap_channels = true; @@ -1436,9 +1483,30 @@ lima_pack_pp_frame_reg(struct lima_context *ctx, uint32_t *frame_reg, break; } + struct lima_pp_wb_reg *wb = (void *)wb_reg; + wb[wb_idx].type = 0x02; /* 2 for color buffer */ + wb[wb_idx].address = res->bo->va; + wb[wb_idx].pixel_format = LIMA_PIXEL_FORMAT_B8G8R8A8; + if (res->tiled) { + wb[wb_idx].pixel_layout = 0x2; + wb[wb_idx].pitch = fb->tiled_w; + } else { + wb[wb_idx].pixel_layout = 0x0; + wb[wb_idx].pitch = res->levels[0].stride / 8; + } + wb[wb_idx].mrt_bits = swap_channels ? 0x4 : 0x0; +} + + +static void +lima_pack_pp_frame_reg(struct lima_context *ctx, uint32_t *frame_reg, + uint32_t *wb_reg) +{ struct lima_context_framebuffer *fb = &ctx->framebuffer; struct lima_pp_frame_reg *frame = (void *)frame_reg; struct lima_screen *screen = lima_screen(ctx->base.screen); + int wb_idx = 0; + frame->render_address = screen->pp_buffer->va + pp_frame_rsw_offset; frame->flags = 0x02; frame->clear_value_depth = ctx->clear.depth; @@ -1469,18 +1537,15 @@ lima_pack_pp_frame_reg(struct lima_context *ctx, uint32_t *frame_reg, frame->blocking = (fb->shift_min << 28) | (fb->shift_h << 16) | fb->shift_w; frame->foureight = 0x8888; - struct lima_pp_wb_reg *wb = (void *)wb_reg; - wb[0].type = 0x02; /* 1 for depth, stencil */ - wb[0].address = res->bo->va; - wb[0].pixel_format = 0x03; /* BGRA8888 */ - if (res->tiled) { - wb[0].pixel_layout = 0x2; - wb[0].pitch = fb->tiled_w; - } else { - wb[0].pixel_layout = 0x0; - wb[0].pitch = res->levels[0].stride / 8; - } - wb[0].mrt_bits = swap_channels ? 0x4 : 0x0; + if (fb->base.nr_cbufs) + lima_pack_wb_cbuf_reg(ctx, wb_reg, wb_idx++); + + /* Mali4x0 can use on-tile buffer for depth/stencil, so to save some + * memory bandwidth don't write depth/stencil back to memory if we're + * rendering to scanout + */ + if (!lima_is_scanout(ctx) && fb->base.zsbuf) + lima_pack_wb_zsbuf_reg(ctx, wb_reg, wb_idx++); } static void @@ -1609,9 +1674,11 @@ _lima_flush(struct lima_context *ctx, bool end_of_frame) ctx->plb_index = (ctx->plb_index + 1) % lima_ctx_num_plb; - /* this surface may need reload when next draw if not end of frame */ - struct lima_surface *surf = lima_surface(ctx->framebuffer.base.cbufs[0]); - surf->reload = !end_of_frame; + if (ctx->framebuffer.base.nr_cbufs) { + /* this surface may need reload when next draw if not end of frame */ + struct lima_surface *surf = lima_surface(ctx->framebuffer.base.cbufs[0]); + surf->reload = !end_of_frame; + } } void diff --git a/src/gallium/drivers/lima/lima_resource.c b/src/gallium/drivers/lima/lima_resource.c index a3edfd0931a..4e215e9e08f 100644 --- a/src/gallium/drivers/lima/lima_resource.c +++ b/src/gallium/drivers/lima/lima_resource.c @@ -192,7 +192,8 @@ _lima_resource_create_with_modifiers(struct pipe_screen *pscreen, if (!should_tile && !drm_find_modifier(DRM_FORMAT_MOD_LINEAR, modifiers, count)) return NULL; - if (should_tile || (templat->bind & PIPE_BIND_RENDER_TARGET)) { + if (should_tile || (templat->bind & PIPE_BIND_RENDER_TARGET) || + (templat->bind & PIPE_BIND_DEPTH_STENCIL)) { should_align_dimensions = true; width = align(templat->width0, 16); height = align(templat->height0, 16); diff --git a/src/gallium/drivers/lima/lima_screen.c b/src/gallium/drivers/lima/lima_screen.c index ae58f7fd82a..cd9639b41e2 100644 --- a/src/gallium/drivers/lima/lima_screen.c +++ b/src/gallium/drivers/lima/lima_screen.c @@ -272,6 +272,9 @@ lima_screen_is_format_supported(struct pipe_screen *pscreen, case PIPE_FORMAT_B8G8R8X8_UNORM: case PIPE_FORMAT_R8G8B8A8_UNORM: case PIPE_FORMAT_R8G8B8X8_UNORM: + case PIPE_FORMAT_Z16_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + case PIPE_FORMAT_Z24X8_UNORM: break; default: return FALSE; @@ -317,6 +320,9 @@ lima_screen_is_format_supported(struct pipe_screen *pscreen, case PIPE_FORMAT_B8G8R8A8_UNORM: case PIPE_FORMAT_A8B8G8R8_SRGB: case PIPE_FORMAT_B8G8R8A8_SRGB: + case PIPE_FORMAT_Z16_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + case PIPE_FORMAT_Z24X8_UNORM: break; default: return FALSE; diff --git a/src/gallium/drivers/lima/lima_state.c b/src/gallium/drivers/lima/lima_state.c index 7985dacd407..1621618c865 100644 --- a/src/gallium/drivers/lima/lima_state.c +++ b/src/gallium/drivers/lima/lima_state.c @@ -47,7 +47,7 @@ lima_set_framebuffer_state(struct pipe_context *pctx, fb->base.samples = framebuffer->samples; - fb->base.nr_cbufs = 1; + fb->base.nr_cbufs = framebuffer->nr_cbufs; pipe_surface_reference(&fb->base.cbufs[0], framebuffer->cbufs[0]); pipe_surface_reference(&fb->base.zsbuf, framebuffer->zsbuf); diff --git a/src/gallium/drivers/lima/lima_texture.c b/src/gallium/drivers/lima/lima_texture.c index 548d9839ff0..90af0dec74b 100644 --- a/src/gallium/drivers/lima/lima_texture.c +++ b/src/gallium/drivers/lima/lima_texture.c @@ -40,9 +40,11 @@ #include #define LIMA_TEXEL_FORMAT_BGR_565 0x0e +#define LIMA_TEXEL_FORMAT_Z16 0x12 #define LIMA_TEXEL_FORMAT_RGB_888 0x15 #define LIMA_TEXEL_FORMAT_RGBA_8888 0x16 #define LIMA_TEXEL_FORMAT_RGBX_8888 0x17 +#define LIMA_TEXEL_FORMAT_Z24S8 0x2c #define lima_tex_list_size 64 @@ -68,6 +70,13 @@ static uint32_t pipe_format_to_lima(enum pipe_format pformat) case PIPE_FORMAT_B5G6R5_UNORM: format = LIMA_TEXEL_FORMAT_BGR_565; break; + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + case PIPE_FORMAT_Z24X8_UNORM: + format = LIMA_TEXEL_FORMAT_Z24S8; + break; + case PIPE_FORMAT_Z16_UNORM: + format = LIMA_TEXEL_FORMAT_Z16; + break; default: assert(0); break;