Mesa (main): lima: implement lima-specific blitter

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jun 9 23:38:48 UTC 2022


Module: Mesa
Branch: main
Commit: 570020c810667b4493f84eae475b57aadf5bee9c
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=570020c810667b4493f84eae475b57aadf5bee9c

Author: Vasily Khoruzhick <anarsoul at gmail.com>
Date:   Mon May 23 17:25:46 2022 -0700

lima: implement lima-specific blitter

It should be more efficient than u_blitter since it skips
vertex shader stage. Also it's a prerequisite for supporting
MSAA since u_blitter can't do MSAA resolve for us.

Reviewed-by: Erico Nunes <nunes.erico at gmail.com>
Signed-off-by: Vasily Khoruzhick <anarsoul at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16686>

---

 docs/drivers/lima.rst                      |   5 +
 src/gallium/drivers/lima/ci/lima-fails.txt |   2 -
 src/gallium/drivers/lima/lima_blit.c       | 304 +++++++++++++++++++++++++++++
 src/gallium/drivers/lima/lima_blit.h       |  28 +++
 src/gallium/drivers/lima/lima_draw.c       |  11 --
 src/gallium/drivers/lima/lima_job.c        | 160 +++++----------
 src/gallium/drivers/lima/lima_job.h        |   3 +
 src/gallium/drivers/lima/lima_resource.c   |   5 +
 src/gallium/drivers/lima/lima_screen.c     |   2 +
 src/gallium/drivers/lima/lima_screen.h     |   1 +
 src/gallium/drivers/lima/lima_util.c       |  12 ++
 src/gallium/drivers/lima/lima_util.h       |   5 +
 src/gallium/drivers/lima/meson.build       |   2 +
 13 files changed, 413 insertions(+), 127 deletions(-)

diff --git a/docs/drivers/lima.rst b/docs/drivers/lima.rst
index 91c16c0c3c5..870517d2002 100644
--- a/docs/drivers/lima.rst
+++ b/docs/drivers/lima.rst
@@ -68,10 +68,14 @@ accepts the following comma-separated list of flags:
 
   ``bocache``
     print debug info for BO cache
+  ``diskcache``
+    print debug info for shader disk cache
   ``dump``
     dump GPU command stream to ``$PWD/lima.dump``
   ``gp``
     print GP shader compiler result of each stage
+  ``noblit``
+    use generic u_blitter instead of lima-specific
   ``nobocache``
     disable BO cache
   ``nogrowheap``
@@ -87,6 +91,7 @@ accepts the following comma-separated list of flags:
   ``singlejob``
     disable multi job optimization
 
+
 .. envvar:: LIMA_CTX_NUM_PLB <int> (None)
 
 set number of PLB per context (used for development purposes)
diff --git a/src/gallium/drivers/lima/ci/lima-fails.txt b/src/gallium/drivers/lima/ci/lima-fails.txt
index a41e3a5ddeb..d8f83aafc38 100644
--- a/src/gallium/drivers/lima/ci/lima-fails.txt
+++ b/src/gallium/drivers/lima/ci/lima-fails.txt
@@ -64,8 +64,6 @@ spec at arb_depth_texture@fbo-depth-gl_depth_component32-blit,Fail
 spec at arb_depth_texture@fbo-depth-gl_depth_component32-copypixels,Fail
 spec at arb_depth_texture@fbo-depth-gl_depth_component32-readpixels,Fail
 spec at arb_depth_texture@fbo-generatemipmap-formats,Fail
-spec at arb_depth_texture@fbo-generatemipmap-formats at GL_DEPTH_COMPONENT16,Fail
-spec at arb_depth_texture@fbo-generatemipmap-formats at GL_DEPTH_COMPONENT16 NPOT,Fail
 spec at arb_depth_texture@fbo-generatemipmap-formats at GL_DEPTH_COMPONENT24,Fail
 spec at arb_depth_texture@fbo-generatemipmap-formats at GL_DEPTH_COMPONENT24 NPOT,Fail
 spec at arb_depth_texture@fbo-generatemipmap-formats at GL_DEPTH_COMPONENT32,Fail
diff --git a/src/gallium/drivers/lima/lima_blit.c b/src/gallium/drivers/lima/lima_blit.c
new file mode 100644
index 00000000000..b7340485fd4
--- /dev/null
+++ b/src/gallium/drivers/lima/lima_blit.c
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2022 Lima Project
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ */
+
+#include "drm-uapi/lima_drm.h"
+
+#include "util/u_math.h"
+#include "util/format/u_format.h"
+#include "util/u_surface.h"
+#include "util/u_inlines.h"
+#include "util/hash_table.h"
+
+#include "lima_context.h"
+#include "lima_gpu.h"
+#include "lima_resource.h"
+#include "lima_texture.h"
+#include "lima_format.h"
+#include "lima_job.h"
+#include "lima_screen.h"
+#include "lima_bo.h"
+#include "lima_parser.h"
+#include "lima_util.h"
+#include "lima_blit.h"
+
+void
+lima_pack_blit_cmd(struct lima_job *job,
+                   struct util_dynarray *cmd_array,
+                   struct pipe_surface *psurf,
+                   const struct pipe_box *src,
+                   const struct pipe_box *dst,
+                   unsigned filter,
+                   bool scissor)
+{
+   #define lima_blit_render_state_offset 0x0000
+   #define lima_blit_gl_pos_offset       0x0040
+   #define lima_blit_varying_offset      0x0080
+   #define lima_blit_tex_desc_offset     0x00c0
+   #define lima_blit_tex_array_offset    0x0100
+   #define lima_blit_buffer_size         0x0140
+
+   struct lima_context *ctx = job->ctx;
+   struct lima_surface *surf = lima_surface(psurf);
+   int level = psurf->u.tex.level;
+   unsigned first_layer = psurf->u.tex.first_layer;
+   float fb_width = dst->width, fb_height = dst->height;
+
+   uint32_t va;
+   void *cpu = lima_job_create_stream_bo(
+      job, LIMA_PIPE_PP, lima_blit_buffer_size, &va);
+
+   struct lima_screen *screen = lima_screen(ctx->base.screen);
+
+   uint32_t reload_shader_first_instr_size =
+      ((uint32_t *)(screen->pp_buffer->map + pp_reload_program_offset))[0] & 0x1f;
+   uint32_t reload_shader_va = screen->pp_buffer->va + pp_reload_program_offset;
+
+   struct lima_render_state reload_render_state = {
+      .alpha_blend = 0xf03b1ad2,
+      .depth_test = 0x0000000e,
+      .depth_range = 0xffff0000,
+      .stencil_front = 0x00000007,
+      .stencil_back = 0x00000007,
+      .multi_sample = 0x0000f007,
+      .shader_address = reload_shader_va | reload_shader_first_instr_size,
+      .varying_types = 0x00000001,
+      .textures_address = va + lima_blit_tex_array_offset,
+      .aux0 = 0x00004021,
+      .varyings_address = va + lima_blit_varying_offset,
+   };
+
+   if (job->key.cbuf) {
+      fb_width = job->key.cbuf->width;
+      fb_height = job->key.cbuf->height;
+   } else {
+      fb_width = job->key.zsbuf->width;
+      fb_height = job->key.zsbuf->height;
+   }
+
+   if (util_format_is_depth_or_stencil(psurf->format)) {
+      reload_render_state.alpha_blend &= 0x0fffffff;
+      if (psurf->format != PIPE_FORMAT_Z16_UNORM)
+         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_blit_render_state_offset, &reload_render_state,
+          sizeof(reload_render_state));
+
+   lima_tex_desc *td = cpu + lima_blit_tex_desc_offset;
+   memset(td, 0, lima_min_tex_desc_size);
+   lima_texture_desc_set_res(ctx, td, psurf->texture, level, level, first_layer);
+   td->format = lima_format_get_texel_reload(psurf->format);
+   td->unnorm_coords = 1;
+   td->sampler_dim = LIMA_SAMPLER_DIM_2D;
+   td->min_img_filter_nearest = 1;
+   td->mag_img_filter_nearest = 1;
+   td->wrap_s = LIMA_TEX_WRAP_CLAMP_TO_EDGE;
+   td->wrap_t = LIMA_TEX_WRAP_CLAMP_TO_EDGE;
+   td->wrap_r = LIMA_TEX_WRAP_CLAMP_TO_EDGE;
+
+   if (filter != PIPE_TEX_FILTER_NEAREST) {
+      td->min_img_filter_nearest = 0;
+      td->mag_img_filter_nearest = 0;
+   }
+
+   uint32_t *ta = cpu + lima_blit_tex_array_offset;
+   ta[0] = va + lima_blit_tex_desc_offset;
+
+   float reload_gl_pos[] = {
+      dst->x + dst->width, dst->y,      0, 1,
+      dst->x,              dst->y,      0, 1,
+      dst->x, dst->y + dst->height,     0, 1,
+   };
+   memcpy(cpu + lima_blit_gl_pos_offset, reload_gl_pos,
+          sizeof(reload_gl_pos));
+
+   float reload_varying[] = {
+      src->x + src->width, src->y,
+      src->x,              src->y,
+      src->x,              src->y + src->height,
+      0, 0, /* unused */
+   };
+   memcpy(cpu + lima_blit_varying_offset, reload_varying,
+          sizeof(reload_varying));
+
+   PLBU_CMD_BEGIN(cmd_array, scissor ? 22 : 20);
+
+   PLBU_CMD_VIEWPORT_LEFT(0);
+   PLBU_CMD_VIEWPORT_RIGHT(fui(fb_width));
+   PLBU_CMD_VIEWPORT_BOTTOM(0);
+   PLBU_CMD_VIEWPORT_TOP(fui(fb_height));
+
+   PLBU_CMD_RSW_VERTEX_ARRAY(
+      va + lima_blit_render_state_offset,
+      va + lima_blit_gl_pos_offset);
+
+
+   if (scissor) {
+      int minx = MIN2(dst->x, dst->x + dst->width);
+      int maxx = MAX2(dst->x, dst->x + dst->width);
+      int miny = MIN2(dst->y, dst->y + dst->height);
+      int maxy = MAX2(dst->y, dst->y + dst->height);
+
+      PLBU_CMD_SCISSORS(minx, maxx, miny, maxy);
+      lima_damage_rect_union(&job->damage_rect, minx, maxx, miny, maxy);
+   }
+
+   PLBU_CMD_UNKNOWN2();
+   PLBU_CMD_UNKNOWN1();
+
+   PLBU_CMD_INDICES(screen->pp_buffer->va + pp_shared_index_offset);
+   PLBU_CMD_INDEXED_DEST(va + lima_blit_gl_pos_offset);
+   PLBU_CMD_DRAW_ELEMENTS(0xf, 0, 3);
+
+   PLBU_CMD_END();
+
+   lima_dump_command_stream_print(job->dump, cpu, lima_blit_buffer_size,
+                                  false, "blit plbu cmd at va %x\n", va);
+}
+
+static struct pipe_surface *
+lima_get_blit_surface(struct pipe_context *pctx,
+                      struct pipe_resource *prsc,
+                      unsigned level)
+{
+   struct pipe_surface tmpl;
+
+   memset(&tmpl, 0, sizeof(tmpl));
+   tmpl.format = prsc->format;
+   tmpl.u.tex.level = level;
+   tmpl.u.tex.first_layer = 0;
+   tmpl.u.tex.last_layer = 0;
+
+   return pctx->create_surface(pctx, prsc, &tmpl);
+}
+
+bool
+lima_do_blit(struct pipe_context *pctx,
+             const struct pipe_blit_info *info)
+{
+   struct lima_context *ctx = lima_context(pctx);
+   unsigned reload_flags = PIPE_CLEAR_COLOR0;
+   uint8_t identity[4] = { PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y,
+                           PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W };
+
+   if (lima_debug & LIMA_DEBUG_NO_BLIT)
+      return false;
+
+   /* Blitting of swizzled formats (R and RG) isn't implemented yet */
+   if (memcmp(identity,
+              lima_format_get_texel_swizzle(info->src.resource->format),
+              sizeof(identity)))
+      return false;
+
+   if (memcmp(identity,
+              lima_format_get_texel_swizzle(info->dst.resource->format),
+              sizeof(identity)))
+      return false;
+
+   if (util_format_is_depth_or_stencil(info->src.resource->format)) {
+      const struct util_format_description *desc =
+         util_format_description(info->src.resource->format);
+      reload_flags = 0;
+      if (util_format_has_depth(desc))
+         reload_flags |= PIPE_CLEAR_DEPTH;
+      if (util_format_has_stencil(desc))
+         reload_flags |= PIPE_CLEAR_STENCIL;
+   }
+
+   if (!lima_format_pixel_supported(info->dst.resource->format))
+      return false;
+
+   if (!lima_format_texel_supported(info->src.resource->format))
+      return false;
+
+   if (info->dst.resource->target != PIPE_TEXTURE_2D ||
+       info->src.resource->target != PIPE_TEXTURE_2D)
+      return false;
+
+   if (info->dst.box.x < 0 || info->dst.box.y < 0 ||
+       info->src.box.x < 0 || info->src.box.y < 0)
+      return false;
+
+   if (info->src.box.depth != 1 ||
+       info->dst.box.depth != 1)
+      return false;
+
+   /* Scissored blit isn't implemented yet */
+   if (info->scissor_enable)
+      return false;
+
+   if ((reload_flags & PIPE_CLEAR_COLOR) && !(info->mask & PIPE_MASK_RGBA))
+      return false;
+
+   if ((reload_flags & PIPE_CLEAR_DEPTH) && !(info->mask & PIPE_MASK_Z))
+      return false;
+
+   if ((reload_flags & PIPE_CLEAR_STENCIL) && !(info->mask & PIPE_MASK_S))
+      return false;
+
+   struct pipe_surface *dst_surf =
+         lima_get_blit_surface(pctx, info->dst.resource, info->dst.level);
+   struct lima_surface *lima_dst_surf = lima_surface(dst_surf);
+
+   struct pipe_surface *src_surf =
+         lima_get_blit_surface(pctx, info->src.resource, info->src.level);
+
+   struct lima_job *job;
+
+   if (util_format_is_depth_or_stencil(info->dst.resource->format))
+      job = lima_job_get_with_fb(ctx, NULL, dst_surf);
+   else
+      job = lima_job_get_with_fb(ctx, dst_surf, NULL);
+
+   struct lima_resource *src_res = lima_resource(src_surf->texture);
+   struct lima_resource *dst_res = lima_resource(dst_surf->texture);
+
+   lima_flush_job_accessing_bo(ctx, src_res->bo, true);
+   lima_flush_job_accessing_bo(ctx, dst_res->bo, true);
+
+   lima_job_add_bo(job, LIMA_PIPE_PP, src_res->bo, LIMA_SUBMIT_BO_READ);
+   _mesa_hash_table_insert(ctx->write_jobs, &dst_res->base, job);
+   lima_job_add_bo(job, LIMA_PIPE_PP, dst_res->bo, LIMA_SUBMIT_BO_WRITE);
+
+   lima_pack_blit_cmd(job, &job->plbu_cmd_array,
+                      src_surf, &info->src.box,
+                      &info->dst.box, info->filter, true);
+
+   bool tile_aligned = false;
+
+   if (info->dst.box.x == 0 && info->dst.box.y == 0 &&
+       info->dst.box.width == lima_dst_surf->base.width &&
+       info->dst.box.height == lima_dst_surf->base.height)
+      tile_aligned = true;
+
+   if (info->dst.box.x % 16 == 0 && info->dst.box.y % 16 == 0 &&
+       info->dst.box.width % 16 == 0 && info->dst.box.height % 16 == 0)
+      tile_aligned = true;
+
+   /* Reload if dest is not aligned to tile boundaries */
+   if (!tile_aligned)
+      lima_dst_surf->reload = reload_flags;
+   else
+      lima_dst_surf->reload = 0;
+
+   job->resolve = reload_flags;
+
+   lima_do_job(job);
+
+   pipe_surface_reference(&dst_surf, NULL);
+   pipe_surface_reference(&src_surf, NULL);
+
+   return true;
+}
diff --git a/src/gallium/drivers/lima/lima_blit.h b/src/gallium/drivers/lima/lima_blit.h
new file mode 100644
index 00000000000..d678bc3cace
--- /dev/null
+++ b/src/gallium/drivers/lima/lima_blit.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 Lima Project
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ */
+
+#ifndef H_LIMA_BLIT
+#define H_LIMA_BLIT
+
+#include <stdbool.h>
+
+struct util_dynarray;
+
+void
+lima_pack_blit_cmd(struct lima_job *job,
+                   struct util_dynarray *cmd,
+                   struct pipe_surface *psurf,
+                   const struct pipe_box *src,
+                   const struct pipe_box *dst,
+                   unsigned filter,
+                   bool scissor);
+
+bool lima_do_blit(struct pipe_context *ctx,
+                  const struct pipe_blit_info *blit_info);
+
+#endif
+
diff --git a/src/gallium/drivers/lima/lima_draw.c b/src/gallium/drivers/lima/lima_draw.c
index 5728cae7e79..1d5a82ff2da 100644
--- a/src/gallium/drivers/lima/lima_draw.c
+++ b/src/gallium/drivers/lima/lima_draw.c
@@ -146,17 +146,6 @@ lima_update_job_wb(struct lima_context *ctx, unsigned buffers)
    job->resolve |= buffers;
 }
 
-static void
-lima_damage_rect_union(struct pipe_scissor_state *rect,
-                       unsigned minx, unsigned maxx,
-                       unsigned miny, unsigned maxy)
-{
-   rect->minx = MIN2(rect->minx, minx);
-   rect->miny = MIN2(rect->miny, miny);
-   rect->maxx = MAX2(rect->maxx, maxx);
-   rect->maxy = MAX2(rect->maxy, maxy);
-}
-
 static void
 lima_clear(struct pipe_context *pctx, unsigned buffers, const struct pipe_scissor_state *scissor_state,
            const union pipe_color_union *color, double depth, unsigned stencil)
diff --git a/src/gallium/drivers/lima/lima_job.c b/src/gallium/drivers/lima/lima_job.c
index 14f52da4c7e..e8fe97317ff 100644
--- a/src/gallium/drivers/lima/lima_job.c
+++ b/src/gallium/drivers/lima/lima_job.c
@@ -45,6 +45,7 @@
 #include "lima_texture.h"
 #include "lima_fence.h"
 #include "lima_gpu.h"
+#include "lima_blit.h"
 
 #define VOID2U64(x) ((uint64_t)(unsigned long)(x))
 
@@ -53,9 +54,19 @@ lima_get_fb_info(struct lima_job *job)
 {
    struct lima_context *ctx = job->ctx;
    struct lima_job_fb_info *fb = &job->fb;
+   struct lima_surface *surf = lima_surface(job->key.cbuf);
 
-   fb->width = ctx->framebuffer.base.width;
-   fb->height = ctx->framebuffer.base.height;
+   if (!surf)
+      surf = lima_surface(job->key.zsbuf);
+
+   if (!surf) {
+      /* We don't have neither cbuf nor zsbuf, use dimensions from ctx */
+      fb->width = ctx->framebuffer.base.width;
+      fb->height =  ctx->framebuffer.base.height;
+   } else {
+      fb->width = surf->base.width;
+      fb->height = surf->base.height;
+   }
 
    int width = align(fb->width, 16) >> 4;
    int height = align(fb->height, 16) >> 4;
@@ -86,7 +97,9 @@ lima_get_fb_info(struct lima_job *job)
 }
 
 static struct lima_job *
-lima_job_create(struct lima_context *ctx)
+lima_job_create(struct lima_context *ctx,
+                struct pipe_surface *cbuf,
+                struct pipe_surface *zsbuf)
 {
    struct lima_job *s;
 
@@ -112,9 +125,8 @@ lima_job_create(struct lima_context *ctx)
    util_dynarray_init(&s->plbu_cmd_array, s);
    util_dynarray_init(&s->plbu_cmd_head, s);
 
-   struct lima_context_framebuffer *fb = &ctx->framebuffer;
-   pipe_surface_reference(&s->key.cbuf, fb->base.cbufs[0]);
-   pipe_surface_reference(&s->key.zsbuf, fb->base.zsbuf);
+   pipe_surface_reference(&s->key.cbuf, cbuf);
+   pipe_surface_reference(&s->key.zsbuf, zsbuf);
 
    lima_get_fb_info(s);
 
@@ -145,20 +157,21 @@ lima_job_free(struct lima_job *job)
    ralloc_free(job);
 }
 
-static struct lima_job *
-_lima_job_get(struct lima_context *ctx)
+struct lima_job *
+lima_job_get_with_fb(struct lima_context *ctx,
+                      struct pipe_surface *cbuf,
+                      struct pipe_surface *zsbuf)
 {
-   struct lima_context_framebuffer *fb = &ctx->framebuffer;
    struct lima_job_key local_key = {
-      .cbuf = fb->base.cbufs[0],
-      .zsbuf = fb->base.zsbuf,
+      .cbuf = cbuf,
+      .zsbuf = zsbuf,
    };
 
    struct hash_entry *entry = _mesa_hash_table_search(ctx->jobs, &local_key);
    if (entry)
       return entry->data;
 
-   struct lima_job *job = lima_job_create(ctx);
+   struct lima_job *job = lima_job_create(ctx, cbuf, zsbuf);
    if (!job)
       return NULL;
 
@@ -167,6 +180,14 @@ _lima_job_get(struct lima_context *ctx)
    return job;
 }
 
+static struct lima_job *
+_lima_job_get(struct lima_context *ctx)
+{
+   struct lima_context_framebuffer *fb = &ctx->framebuffer;
+
+   return lima_job_get_with_fb(ctx, fb->base.cbufs[0], fb->base.zsbuf);
+}
+
 /*
  * Note: this function can only be called in draw code path,
  * must not exist in flush code path.
@@ -337,112 +358,23 @@ lima_fb_zsbuf_needs_reload(struct lima_job *job)
 static void
 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
-   #define lima_reload_varying_offset      0x0080
-   #define lima_reload_tex_desc_offset     0x00c0
-   #define lima_reload_tex_array_offset    0x0100
-   #define lima_reload_buffer_size         0x0140
-
-   struct lima_context *ctx = job->ctx;
-   struct lima_surface *surf = lima_surface(psurf);
-   int level = psurf->u.tex.level;
-   unsigned first_layer = psurf->u.tex.first_layer;
-
-   uint32_t va;
-   void *cpu = lima_job_create_stream_bo(
-      job, LIMA_PIPE_PP, lima_reload_buffer_size, &va);
-
-   struct lima_screen *screen = lima_screen(ctx->base.screen);
-
-   uint32_t reload_shader_first_instr_size =
-      ((uint32_t *)(screen->pp_buffer->map + pp_reload_program_offset))[0] & 0x1f;
-   uint32_t reload_shader_va = screen->pp_buffer->va + pp_reload_program_offset;
-
-   struct lima_render_state reload_render_state = {
-      .alpha_blend = 0xf03b1ad2,
-      .depth_test = 0x0000000e,
-      .depth_range = 0xffff0000,
-      .stencil_front = 0x00000007,
-      .stencil_back = 0x00000007,
-      .multi_sample = 0x0000f007,
-      .shader_address = reload_shader_va | reload_shader_first_instr_size,
-      .varying_types = 0x00000001,
-      .textures_address = va + lima_reload_tex_array_offset,
-      .aux0 = 0x00004021,
-      .varyings_address = va + lima_reload_varying_offset,
-   };
-
-   if (util_format_is_depth_or_stencil(psurf->format)) {
-      reload_render_state.alpha_blend &= 0x0fffffff;
-      if (psurf->format != PIPE_FORMAT_Z16_UNORM)
-         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, psurf->texture, level, level, first_layer);
-   td->format = lima_format_get_texel_reload(psurf->format);
-   td->unnorm_coords = 1;
-   td->sampler_dim = LIMA_SAMPLER_DIM_2D;
-   td->min_img_filter_nearest = 1;
-   td->mag_img_filter_nearest = 1;
-   td->wrap_s = LIMA_TEX_WRAP_CLAMP_TO_EDGE;
-   td->wrap_t = LIMA_TEX_WRAP_CLAMP_TO_EDGE;
-   td->wrap_r = LIMA_TEX_WRAP_CLAMP_TO_EDGE;
-
-   uint32_t *ta = cpu + lima_reload_tex_array_offset;
-   ta[0] = va + lima_reload_tex_desc_offset;
-
    struct lima_job_fb_info *fb = &job->fb;
-   float reload_gl_pos[] = {
-      fb->width, 0,          0, 1,
-      0,         0,          0, 1,
-      0,         fb->height, 0, 1,
+   struct pipe_box src = {
+      .x = 0,
+      .y = 0,
+      .width = fb->width,
+      .height = fb->height,
    };
-   memcpy(cpu + lima_reload_gl_pos_offset, reload_gl_pos,
-          sizeof(reload_gl_pos));
 
-   float reload_varying[] = {
-      fb->width, 0,          0, 0,
-      0,         fb->height, 0, 0,
+   struct pipe_box dst = {
+      .x = 0,
+      .y = 0,
+      .width = fb->width,
+      .height = fb->height,
    };
-   memcpy(cpu + lima_reload_varying_offset, reload_varying,
-          sizeof(reload_varying));
-
-   PLBU_CMD_BEGIN(&job->plbu_cmd_head, 20);
-
-   PLBU_CMD_VIEWPORT_LEFT(0);
-   PLBU_CMD_VIEWPORT_RIGHT(fui(fb->width));
-   PLBU_CMD_VIEWPORT_BOTTOM(0);
-   PLBU_CMD_VIEWPORT_TOP(fui(fb->height));
-
-   PLBU_CMD_RSW_VERTEX_ARRAY(
-      va + lima_reload_render_state_offset,
-      va + lima_reload_gl_pos_offset);
-
-   PLBU_CMD_UNKNOWN2();
-   PLBU_CMD_UNKNOWN1();
-
-   PLBU_CMD_INDICES(screen->pp_buffer->va + pp_shared_index_offset);
-   PLBU_CMD_INDEXED_DEST(va + lima_reload_gl_pos_offset);
-   PLBU_CMD_DRAW_ELEMENTS(0xf, 0, 3);
-
-   PLBU_CMD_END();
-
-   lima_dump_command_stream_print(job->dump, cpu, lima_reload_buffer_size,
-                                  false, "reload plbu cmd at va %x\n", va);
+   lima_pack_blit_cmd(job, &job->plbu_cmd_head,
+                      psurf, &src, &dst,
+                      PIPE_TEX_FILTER_NEAREST, false);
 }
 
 static void
diff --git a/src/gallium/drivers/lima/lima_job.h b/src/gallium/drivers/lima/lima_job.h
index a43b8be1c10..0eb05a5378c 100644
--- a/src/gallium/drivers/lima/lima_job.h
+++ b/src/gallium/drivers/lima/lima_job.h
@@ -95,6 +95,9 @@ lima_job_has_draw_pending(struct lima_job *job)
 }
 
 struct lima_job *lima_job_get(struct lima_context *ctx);
+struct lima_job * lima_job_get_with_fb(struct lima_context *ctx,
+                                       struct pipe_surface *cbuf,
+                                       struct pipe_surface *zsbuf);
 
 bool lima_job_add_bo(struct lima_job *job, int pipe,
                      struct lima_bo *bo, uint32_t flags);
diff --git a/src/gallium/drivers/lima/lima_resource.c b/src/gallium/drivers/lima/lima_resource.c
index e8f5aa6e620..9793fac9fdf 100644
--- a/src/gallium/drivers/lima/lima_resource.c
+++ b/src/gallium/drivers/lima/lima_resource.c
@@ -45,6 +45,7 @@
 #include "lima_resource.h"
 #include "lima_bo.h"
 #include "lima_util.h"
+#include "lima_blit.h"
 
 #include "pan_minmax_cache.h"
 #include "pan_tiling.h"
@@ -855,6 +856,10 @@ lima_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
    struct lima_context *ctx = lima_context(pctx);
    struct pipe_blit_info info = *blit_info;
 
+   if (lima_do_blit(pctx, blit_info)) {
+       return;
+   }
+
    if (util_try_blit_via_copy_region(pctx, &info, false)) {
       return; /* done */
    }
diff --git a/src/gallium/drivers/lima/lima_screen.c b/src/gallium/drivers/lima/lima_screen.c
index 9eadf44b48a..90dcbe8383f 100644
--- a/src/gallium/drivers/lima/lima_screen.c
+++ b/src/gallium/drivers/lima/lima_screen.c
@@ -598,6 +598,8 @@ static const struct debug_named_value lima_debug_options[] = {
           "Precompile shaders for shader-db" },
         { "diskcache", LIMA_DEBUG_DISK_CACHE,
           "print debug info for shader disk cache" },
+        { "noblit", LIMA_DEBUG_NO_BLIT,
+          "use generic u_blitter instead of lima-specific" },
         { NULL }
 };
 
diff --git a/src/gallium/drivers/lima/lima_screen.h b/src/gallium/drivers/lima/lima_screen.h
index bc08a490236..fe2edf08d74 100644
--- a/src/gallium/drivers/lima/lima_screen.h
+++ b/src/gallium/drivers/lima/lima_screen.h
@@ -45,6 +45,7 @@
 #define LIMA_DEBUG_SINGLE_JOB     (1 << 8)
 #define LIMA_DEBUG_PRECOMPILE     (1 << 9)
 #define LIMA_DEBUG_DISK_CACHE     (1 << 10)
+#define LIMA_DEBUG_NO_BLIT        (1 << 11)
 
 extern uint32_t lima_debug;
 extern int lima_ctx_num_plb;
diff --git a/src/gallium/drivers/lima/lima_util.c b/src/gallium/drivers/lima/lima_util.c
index 832fbf68ec4..cf3fe2da04a 100644
--- a/src/gallium/drivers/lima/lima_util.c
+++ b/src/gallium/drivers/lima/lima_util.c
@@ -29,6 +29,7 @@
 
 #include "util/u_debug.h"
 #include "util/u_memory.h"
+#include "util/u_box.h"
 
 #include "lima_util.h"
 #include "lima_parser.h"
@@ -182,3 +183,14 @@ _lima_dump_command_stream_print(struct lima_dump *dump, void *data,
 
    lima_dump_blob(dump->fp, data, size, is_float);
 }
+
+void
+lima_damage_rect_union(struct pipe_scissor_state *rect,
+                       unsigned minx, unsigned maxx,
+                       unsigned miny, unsigned maxy)
+{
+   rect->minx = MIN2(rect->minx, minx);
+   rect->miny = MIN2(rect->miny, miny);
+   rect->maxx = MAX2(rect->maxx, maxx);
+   rect->maxy = MAX2(rect->maxy, maxy);
+}
diff --git a/src/gallium/drivers/lima/lima_util.h b/src/gallium/drivers/lima/lima_util.h
index ebab8a40e62..af3a75ea7fc 100644
--- a/src/gallium/drivers/lima/lima_util.h
+++ b/src/gallium/drivers/lima/lima_util.h
@@ -55,4 +55,9 @@ void _lima_dump_command_stream_print(struct lima_dump *dump, void *data,
          _lima_dump_command_stream_print(dump, __VA_ARGS__); \
    } while (0)
 
+struct pipe_scissor_state;
+
+void lima_damage_rect_union(struct pipe_scissor_state *rect,
+                            unsigned minx, unsigned maxx,
+                            unsigned miny, unsigned maxy);
 #endif
diff --git a/src/gallium/drivers/lima/meson.build b/src/gallium/drivers/lima/meson.build
index 6810c362ccf..5d8f21c2cf8 100644
--- a/src/gallium/drivers/lima/meson.build
+++ b/src/gallium/drivers/lima/meson.build
@@ -82,6 +82,8 @@ files_lima = files(
   'lima_format.h',
   'lima_format.c',
   'lima_gpu.h',
+  'lima_blit.c',
+  'lima_blit.h',
 )
 
 lima_nir_algebraic_c = custom_target(



More information about the mesa-commit mailing list