lima: implement zsbuf reload
authorIcenowy Zheng <icenowy@aosc.io>
Thu, 6 Feb 2020 16:53:46 +0000 (00:53 +0800)
committerMarge Bot <eric+marge@anholt.net>
Wed, 18 Mar 2020 08:36:17 +0000 (08:36 +0000)
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 <anarsoul@gmail.com>
Reviewed-by: Andreas Baierl <ichgeh@imkreisrum.de>
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4197>

.gitlab-ci/deqp-lima-fails.txt
src/gallium/drivers/lima/lima_draw.c
src/gallium/drivers/lima/lima_format.c
src/gallium/drivers/lima/lima_format.h
src/gallium/drivers/lima/lima_job.c
src/gallium/drivers/lima/lima_resource.c
src/gallium/drivers/lima/lima_resource.h

index 28948b2..211a0f1 100644 (file)
@@ -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
index 47f6d2b..9b6d972 100644 (file)
@@ -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;
 
index 5fe7e40..524d127 100644 (file)
@@ -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),
@@ -132,6 +134,18 @@ lima_format_get_texel(enum pipe_format f)
 }
 
 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)
 {
    return lima_format_table[f].pixel;
index e3d7e9f..29faaac 100644 (file)
@@ -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);
 
index 3a00d68..c628ff0 100644 (file)
@@ -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)
index 9f429f8..e60a46b 100644 (file)
@@ -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;
 }
index 0b2d150..36ea605 100644 (file)
@@ -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 {