From: Icenowy Zheng Date: Thu, 6 Feb 2020 16:53:46 +0000 (+0800) Subject: lima: implement zsbuf reload X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9205762caece0c4b9ecea3d56f72c6980935633a;p=mesa.git lima: implement zsbuf reload Fragment shader can write depth and stencil if we set necessary flags in RSW. In addition to that we need to use special format for Z24S8. Original format is apparently Z24X8 since we can't sample stencil in GLES2. This new format also seems to use several components for storing depth since we saw r != g != b when sampling with this format. [vasily: - initialize clear->depth to 0xffffff if we reload depth, just like blob does. Reloading doesn't work otherwise - use single bitmap for reload type] Reviewed-by: Vasily Khoruzhick Reviewed-by: Andreas Baierl Signed-off-by: Icenowy Zheng Signed-off-by: Vasily Khoruzhick Part-of: --- diff --git a/.gitlab-ci/deqp-lima-fails.txt b/.gitlab-ci/deqp-lima-fails.txt index 28948b2adf0..211a0f14052 100644 --- a/.gitlab-ci/deqp-lima-fails.txt +++ b/.gitlab-ci/deqp-lima-fails.txt @@ -4,27 +4,6 @@ dEQP-GLES2.functional.clipping.triangle_vertex.clip_two.clip_neg_x_neg_y_pos_z_a dEQP-GLES2.functional.clipping.triangle_vertex.clip_two.clip_neg_x_pos_y_pos_z_and_pos_x_neg_y_neg_z dEQP-GLES2.functional.clipping.triangle_vertex.clip_two.clip_pos_x_neg_y_pos_z_and_neg_x_pos_y_neg_z dEQP-GLES2.functional.clipping.triangle_vertex.clip_two.clip_pos_x_pos_y_pos_z_and_neg_x_neg_y_neg_z -dEQP-GLES2.functional.depth_stencil_clear.depth_stencil_masked -dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.no_rebind_rbo_rgb565_depth_component16 -dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.no_rebind_rbo_rgb565_stencil_index8 -dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.no_rebind_rbo_rgb5_a1_depth_component16 -dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.no_rebind_rbo_rgb5_a1_stencil_index8 -dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.no_rebind_rbo_rgba4_depth_component16 -dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.no_rebind_rbo_rgba4_stencil_index8 -dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.no_rebind_tex2d_rgba_depth_component16 -dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.no_rebind_tex2d_rgba_stencil_index8 -dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.no_rebind_tex2d_rgb_depth_component16 -dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.no_rebind_tex2d_rgb_stencil_index8 -dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.rebind_rbo_rgb565_depth_component16 -dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.rebind_rbo_rgb565_stencil_index8 -dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.rebind_rbo_rgb5_a1_depth_component16 -dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.rebind_rbo_rgb5_a1_stencil_index8 -dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.rebind_rbo_rgba4_depth_component16 -dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.rebind_rbo_rgba4_stencil_index8 -dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.rebind_tex2d_rgba_depth_component16 -dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.rebind_tex2d_rgba_stencil_index8 -dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.rebind_tex2d_rgb_depth_component16 -dEQP-GLES2.functional.fbo.render.recreate_colorbuffer.rebind_tex2d_rgb_stencil_index8 dEQP-GLES2.functional.fbo.render.shared_depthbuffer.rbo_rgb565_depth_component16 dEQP-GLES2.functional.fbo.render.shared_depthbuffer.rbo_rgb5_a1_depth_component16 dEQP-GLES2.functional.fbo.render.shared_depthbuffer.rbo_rgba4_depth_component16 diff --git a/src/gallium/drivers/lima/lima_draw.c b/src/gallium/drivers/lima/lima_draw.c index 47f6d2bfbf5..9b6d972eb1d 100644 --- a/src/gallium/drivers/lima/lima_draw.c +++ b/src/gallium/drivers/lima/lima_draw.c @@ -118,7 +118,7 @@ lima_clear(struct pipe_context *pctx, unsigned buffers, /* no need to reload if cleared */ if (ctx->framebuffer.base.nr_cbufs && (buffers & PIPE_CLEAR_COLOR0)) { struct lima_surface *surf = lima_surface(ctx->framebuffer.base.cbufs[0]); - surf->reload = false; + surf->reload &= ~PIPE_CLEAR_COLOR0; } struct lima_job_clear *clear = &job->clear; @@ -138,11 +138,20 @@ lima_clear(struct pipe_context *pctx, unsigned buffers, float_to_ushort(color->f[0]); } - if (buffers & PIPE_CLEAR_DEPTH) + struct lima_surface *zsbuf = lima_surface(ctx->framebuffer.base.zsbuf); + + if (buffers & PIPE_CLEAR_DEPTH) { clear->depth = util_pack_z(PIPE_FORMAT_Z24X8_UNORM, depth); + if (zsbuf) + zsbuf->reload &= ~PIPE_CLEAR_DEPTH; + } else + clear->depth = 0x00ffffff; - if (buffers & PIPE_CLEAR_STENCIL) + if (buffers & PIPE_CLEAR_STENCIL) { clear->stencil = stencil; + if (zsbuf) + zsbuf->reload &= ~PIPE_CLEAR_STENCIL; + } ctx->dirty |= LIMA_CONTEXT_DIRTY_CLEAR; diff --git a/src/gallium/drivers/lima/lima_format.c b/src/gallium/drivers/lima/lima_format.c index 5fe7e406b31..524d12773e8 100644 --- a/src/gallium/drivers/lima/lima_format.c +++ b/src/gallium/drivers/lima/lima_format.c @@ -44,7 +44,9 @@ #define LIMA_TEXEL_FORMAT_RGBA_8888 0x16 #define LIMA_TEXEL_FORMAT_RGBX_8888 0x17 #define LIMA_TEXEL_FORMAT_ETC1_RGB8 0x20 -#define LIMA_TEXEL_FORMAT_Z24S8 0x2c +#define LIMA_TEXEL_FORMAT_Z24X8 0x2c +/* This format is only used for depth/stencil reload */ +#define LIMA_TEXEL_FORMAT_Z24S8_RLD 0x32 #define LIMA_TEXEL_FORMAT_NONE -1 #define LIMA_PIXEL_FORMAT_B5G6R5 0x00 @@ -81,8 +83,8 @@ static const struct lima_format lima_format_table[] = { /* BGRA_5551 seems to need channel layout 0x8565, it's not a typo */ LIMA_FORMAT(B5G5R5A1_UNORM, BGRA_5551, B5G5R5A1, false, 0x8565), LIMA_FORMAT(B4G4R4A4_UNORM, BGRA_4444, B4G4R4A4, false, 0x8444), - LIMA_FORMAT(Z24_UNORM_S8_UINT, Z24S8, Z24S8, false, 0x0000), - LIMA_FORMAT(Z24X8_UNORM, Z24S8, Z24S8, false, 0x0000), + LIMA_FORMAT(Z24_UNORM_S8_UINT, Z24X8, Z24S8, false, 0x0000), + LIMA_FORMAT(Z24X8_UNORM, Z24X8, Z24S8, false, 0x0000), LIMA_FORMAT(L16_UNORM, L16, NONE, false, 0x0000), LIMA_FORMAT(L8_UNORM, L8, NONE, false, 0x0000), LIMA_FORMAT(A16_UNORM, A16, NONE, false, 0x0000), @@ -131,6 +133,18 @@ lima_format_get_texel(enum pipe_format f) return lima_format_table[f].texel; } +int +lima_format_get_texel_reload(enum pipe_format f) +{ + switch (f) { + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + case PIPE_FORMAT_Z24X8_UNORM: + return LIMA_TEXEL_FORMAT_Z24S8_RLD; + default: + return lima_format_get_texel(f); + } +} + int lima_format_get_pixel(enum pipe_format f) { diff --git a/src/gallium/drivers/lima/lima_format.h b/src/gallium/drivers/lima/lima_format.h index e3d7e9f9441..29faaac3a7b 100644 --- a/src/gallium/drivers/lima/lima_format.h +++ b/src/gallium/drivers/lima/lima_format.h @@ -32,6 +32,7 @@ bool lima_format_texel_supported(enum pipe_format f); bool lima_format_pixel_supported(enum pipe_format f); int lima_format_get_texel(enum pipe_format f); int lima_format_get_pixel(enum pipe_format f); +int lima_format_get_texel_reload(enum pipe_format f); bool lima_format_get_swap_rb(enum pipe_format f); uint32_t lima_format_get_channel_layout(enum pipe_format f); diff --git a/src/gallium/drivers/lima/lima_job.c b/src/gallium/drivers/lima/lima_job.c index 3a00d689242..c628ff0a4e6 100644 --- a/src/gallium/drivers/lima/lima_job.c +++ b/src/gallium/drivers/lima/lima_job.c @@ -31,6 +31,7 @@ #include "util/ralloc.h" #include "util/os_time.h" #include "util/hash_table.h" +#include "util/format/u_format.h" #include "util/u_upload_mgr.h" #include "util/u_inlines.h" @@ -296,9 +297,8 @@ lima_job_get_damage(struct lima_job *job) } static bool -lima_fb_need_reload(struct lima_job *job) +lima_fb_cbuf_needs_reload(struct lima_job *job) { - /* Depth buffer is always discarded */ if (!(job->key.cbuf && (job->resolve & PIPE_CLEAR_COLOR0))) return false; @@ -312,14 +312,27 @@ lima_fb_need_reload(struct lima_job *job) // return true; return true; } - else if (surf->reload) + else if (surf->reload & PIPE_CLEAR_COLOR0) + return true; + + return false; +} + +static bool +lima_fb_zsbuf_needs_reload(struct lima_job *job) +{ + if (!(job->key.zsbuf && (job->resolve & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)))) + return false; + + struct lima_surface *surf = lima_surface(job->key.zsbuf); + if (surf->reload & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) return true; return false; } static void -lima_pack_reload_plbu_cmd(struct lima_job *job) +lima_pack_reload_plbu_cmd(struct lima_job *job, struct pipe_surface *psurf) { #define lima_reload_render_state_offset 0x0000 #define lima_reload_gl_pos_offset 0x0040 @@ -329,6 +342,7 @@ lima_pack_reload_plbu_cmd(struct lima_job *job) #define lima_reload_buffer_size 0x0140 struct lima_context *ctx = job->ctx; + struct lima_surface *surf = lima_surface(psurf); uint32_t va; void *cpu = lima_job_create_stream_bo( @@ -353,12 +367,27 @@ lima_pack_reload_plbu_cmd(struct lima_job *job) .aux0 = 0x00004021, .varyings_address = va + lima_reload_varying_offset, }; + + if (util_format_is_depth_or_stencil(psurf->format)) { + reload_render_state.alpha_blend &= 0x0fffffff; + reload_render_state.depth_test |= 0x400; + if (surf->reload & PIPE_CLEAR_DEPTH) + reload_render_state.depth_test |= 0x801; + if (surf->reload & PIPE_CLEAR_STENCIL) { + reload_render_state.depth_test |= 0x1000; + reload_render_state.stencil_front = 0x0000024f; + reload_render_state.stencil_back = 0x0000024f; + reload_render_state.stencil_test = 0x0000ffff; + } + } + memcpy(cpu + lima_reload_render_state_offset, &reload_render_state, sizeof(reload_render_state)); lima_tex_desc *td = cpu + lima_reload_tex_desc_offset; memset(td, 0, lima_min_tex_desc_size); - lima_texture_desc_set_res(ctx, td, job->key.cbuf->texture, 0, 0); + lima_texture_desc_set_res(ctx, td, psurf->texture, 0, 0); + td->format = lima_format_get_texel_reload(psurf->format); td->unnorm_coords = 1; td->texture_type = LIMA_TEXTURE_TYPE_2D; td->min_img_filter_nearest = 1; @@ -426,8 +455,11 @@ lima_pack_head_plbu_cmd(struct lima_job *job) PLBU_CMD_END(); - if (lima_fb_need_reload(job)) - lima_pack_reload_plbu_cmd(job); + if (lima_fb_cbuf_needs_reload(job)) + lima_pack_reload_plbu_cmd(job, job->key.cbuf); + + if (lima_fb_zsbuf_needs_reload(job)) + lima_pack_reload_plbu_cmd(job, job->key.zsbuf); } static void @@ -986,10 +1018,15 @@ lima_do_job(struct lima_job *job) ctx->plb_index = (ctx->plb_index + 1) % lima_ctx_num_plb; + /* Set reload flags for next draw. It'll be unset if buffer is cleared */ if (job->key.cbuf && (job->resolve & PIPE_CLEAR_COLOR0)) { - /* Set reload flag for next draw. It'll be unset if buffer is cleared */ struct lima_surface *surf = lima_surface(job->key.cbuf); - surf->reload = true; + surf->reload = PIPE_CLEAR_COLOR0; + } + + if (job->key.zsbuf && (job->resolve & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))) { + struct lima_surface *surf = lima_surface(job->key.zsbuf); + surf->reload = (job->resolve & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)); } if (ctx->job == job) diff --git a/src/gallium/drivers/lima/lima_resource.c b/src/gallium/drivers/lima/lima_resource.c index 9f429f8c32a..e60a46b7ae8 100644 --- a/src/gallium/drivers/lima/lima_resource.c +++ b/src/gallium/drivers/lima/lima_resource.c @@ -508,7 +508,13 @@ lima_surface_create(struct pipe_context *pctx, surf->tiled_w = align(psurf->width, 16) >> 4; surf->tiled_h = align(psurf->height, 16) >> 4; - surf->reload = true; + surf->reload = 0; + if (util_format_has_stencil(util_format_description(psurf->format))) + surf->reload |= PIPE_CLEAR_STENCIL; + if (util_format_has_depth(util_format_description(psurf->format))) + surf->reload |= PIPE_CLEAR_DEPTH; + if (!util_format_is_depth_or_stencil(psurf->format)) + surf->reload |= PIPE_CLEAR_COLOR0; return &surf->base; } diff --git a/src/gallium/drivers/lima/lima_resource.h b/src/gallium/drivers/lima/lima_resource.h index 0b2d150b5ee..36ea605c6b0 100644 --- a/src/gallium/drivers/lima/lima_resource.h +++ b/src/gallium/drivers/lima/lima_resource.h @@ -62,7 +62,7 @@ struct lima_resource { struct lima_surface { struct pipe_surface base; int tiled_w, tiled_h; - bool reload; + unsigned reload; }; struct lima_transfer {