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 28948b2adf05af36c06bf26dca30c9ccc9a7c968..211a0f14052b4d35f069ca40f0f02722a627e0d7 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 47f6d2bfbf590704d52f439df5d2cb3e3d5c7c02..9b6d972eb1ddd314c5f95787ccc71b4089b6a4bd 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 5fe7e406b31849f72b8dc02ea003e6051887dadc..524d12773e8c6f6e616f58a9732c30a92ad33fed 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),
@@ -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)
 {
index e3d7e9f9441e79a4efe1b50cc67fbe0877339d97..29faaac3a7bd000ce55638e7ff9b177fc72cbd28 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 3a00d6892426b3efc0942428f46b1ac64cfb7e97..c628ff0a4e6af23b88e60cd5b62e57d626bac03e 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 9f429f8c32aa665fdf9f3789f53f1f5b8c390482..e60a46b7ae8e80155f4dbffc9ae127e39557dc41 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 0b2d150b5eecd676b736039f3a6a8ecae4941cd5..36ea605c6b038070e4ddd239a67564f7fc6107f1 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 {