Mesa (main): i915g: Move cbuf color swizzle lookup to CSO creation time.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jun 22 18:38:53 UTC 2021


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

Author: Emma Anholt <emma at anholt.net>
Date:   Sun Jun 20 09:19:59 2021 -0700

i915g: Move cbuf color swizzle lookup to CSO creation time.

Saves walking the loop, and makes a nice place to store a swizzle for use
in other atoms.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11512>

---

 src/gallium/drivers/i915/i915_clear.c        |  2 +-
 src/gallium/drivers/i915/i915_context.h      |  8 ++++-
 src/gallium/drivers/i915/i915_state_emit.c   |  7 ++--
 src/gallium/drivers/i915/i915_state_static.c | 49 +++++-----------------------
 src/gallium/drivers/i915/i915_surface.c      | 27 +++++++++++++++
 5 files changed, 47 insertions(+), 46 deletions(-)

diff --git a/src/gallium/drivers/i915/i915_clear.c b/src/gallium/drivers/i915/i915_clear.c
index 814fc90b214..e89c4e2f0f6 100644
--- a/src/gallium/drivers/i915/i915_clear.c
+++ b/src/gallium/drivers/i915/i915_clear.c
@@ -73,7 +73,7 @@ i915_clear_emit(struct pipe_context *pipe, unsigned buffers,
       }
 
       /* correctly swizzle clear value */
-      if (i915->current.target_fixup_format)
+      if (i915->current.fixup_swizzle)
          util_pack_color(color->f, cbuf->format, &u_color);
       else
          util_pack_color(color->f, PIPE_FORMAT_B8G8R8A8_UNORM, &u_color);
diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h
index 65de266399d..a5f893bbd63 100644
--- a/src/gallium/drivers/i915/i915_context.h
+++ b/src/gallium/drivers/i915/i915_context.h
@@ -170,7 +170,8 @@ struct i915_state
    unsigned dst_buf_vars;
    uint32_t draw_offset;
    uint32_t draw_size;
-   uint32_t target_fixup_format;
+
+   /* Reswizzle for OC writes in PIXEL_SHADER_PROGRAM, or 0 if unnecessary. */
    uint32_t fixup_swizzle;
 
    unsigned id;			/* track lost context events */
@@ -214,6 +215,11 @@ struct i915_sampler_state {
 struct i915_surface {
    struct pipe_surface templ;
    uint32_t buf_info; /* _3DSTATE_BUF_INFO_CMD flags */
+
+   /* PIXEL_SHADER_PROGRAM swizzle for OC buffer to handle the cbuf format (or 0 if none). */
+   uint32_t oc_swizzle;
+   /* cbuf swizzle from dst r/g/b/a channels in memory to channels of gallium API. */
+   uint8_t color_swizzle[4];
 };
 
 struct i915_velems_state {
diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c
index 9f0f9e33ca3..3e0da67cff5 100644
--- a/src/gallium/drivers/i915/i915_state_emit.c
+++ b/src/gallium/drivers/i915/i915_state_emit.c
@@ -179,7 +179,8 @@ static void emit_immediate_s6(struct i915_context *i915, uint imm)
     * and therefore we need to use the color factor for alphas. */
    uint srcRGB;
 
-   if (i915->current.target_fixup_format == PIPE_FORMAT_A8_UNORM) {
+   if (i915->framebuffer.cbufs[0] &&
+       i915->framebuffer.cbufs[0]->format == PIPE_FORMAT_A8_UNORM) {
       srcRGB = (imm >> S6_CBUF_SRC_BLEND_FACT_SHIFT) & BLENDFACT_MASK;
       if (srcRGB == BLENDFACT_DST_ALPHA)
          srcRGB = BLENDFACT_DST_COLR;
@@ -425,7 +426,7 @@ validate_program(struct i915_context *i915, unsigned *batch_space)
 {
    uint additional_size = 0;
 
-   additional_size += i915->current.target_fixup_format ? 3 : 0;
+   additional_size += i915->current.fixup_swizzle ? 3 : 0;
 
    /* we need more batch space if we want to emulate rgba framebuffers */
    *batch_space = i915->fs->decl_len + i915->fs->program_len + additional_size;
@@ -464,7 +465,7 @@ emit_program(struct i915_context *i915)
    }
 
    /* we emit an additional mov with swizzle to fake RGBA framebuffers */
-   if (i915->current.target_fixup_format) {
+   if (i915->current.fixup_swizzle) {
       /* mov out_color, out_color.zyxw */
       OUT_BATCH(A0_MOV |
                 (REG_TYPE_OC << A0_DEST_TYPE_SHIFT) |
diff --git a/src/gallium/drivers/i915/i915_state_static.c b/src/gallium/drivers/i915/i915_state_static.c
index 3f6923c15ab..2d0a7416072 100644
--- a/src/gallium/drivers/i915/i915_state_static.c
+++ b/src/gallium/drivers/i915/i915_state_static.c
@@ -82,6 +82,7 @@ static void update_framebuffer(struct i915_context *i915)
    unsigned x, y;
    int layer;
    uint32_t draw_offset, draw_size;
+   uint32_t oc_swizzle = 0;
 
    if (cbuf_surface) {
       struct i915_surface *surf = i915_surface(cbuf_surface);
@@ -95,6 +96,8 @@ static void update_framebuffer(struct i915_context *i915)
 
       x = tex->image_offset[cbuf_surface->u.tex.level][layer].nblocksx;
       y = tex->image_offset[cbuf_surface->u.tex.level][layer].nblocksy;
+
+      oc_swizzle = surf->oc_swizzle;
    } else {
       i915->current.cbuf_bo = NULL;
       x = y = 0;
@@ -134,6 +137,11 @@ static void update_framebuffer(struct i915_context *i915)
 
    i915->hardware_dirty |= I915_HW_STATIC;
 
+   if (i915->current.fixup_swizzle != oc_swizzle) {
+      i915->current.fixup_swizzle = oc_swizzle;
+      i915->hardware_dirty |= I915_HW_PROGRAM;
+   }
+
    /* flush the cache in case we sample from the old renderbuffers */
    i915_set_flush_dirty(i915, I915_FLUSH_CACHE);
 }
@@ -144,45 +152,12 @@ struct i915_tracked_state i915_hw_framebuffer = {
    I915_NEW_FRAMEBUFFER
 };
 
-static uint32_t need_target_fixup(struct pipe_surface* p, uint32_t *fixup)
-{
-   const struct
-   {
-      enum pipe_format format;
-      uint hw_swizzle;
-   } fixup_formats[] = {
-      { PIPE_FORMAT_R8G8B8A8_UNORM, 0x21030000 /* BGRA */},
-      { PIPE_FORMAT_R8G8B8X8_UNORM, 0x21030000 /* BGRX */},
-      { PIPE_FORMAT_L8_UNORM,       0x00030000 /* RRRA */},
-      { PIPE_FORMAT_I8_UNORM,       0x00030000 /* RRRA */},
-      { PIPE_FORMAT_A8_UNORM,       0x33330000 /* AAAA */},
-      { PIPE_FORMAT_NONE,           0x00000000},
-   };
-
-   enum pipe_format f;
-   /* if we don't have a surface bound yet, we don't need to fixup the shader */
-   if (!p)
-      return 0;
-
-   f = p->format;
-   for(int i = 0; fixup_formats[i].format != PIPE_FORMAT_NONE; i++)
-      if (fixup_formats[i].format == f) {
-         *fixup = fixup_formats[i].hw_swizzle;
-         return f;
-      }
-
-   *fixup = 0;
-   return 0;
-}
-
 static void update_dst_buf_vars(struct i915_context *i915)
 {
    struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0];
    struct pipe_surface *depth_surface = i915->framebuffer.zsbuf;
    uint32_t dst_buf_vars, cformat, zformat;
    uint32_t early_z = 0;
-   uint32_t fixup = 0;
-   int need_fixup;
 
    if (cbuf_surface)
       cformat = cbuf_surface->format;
@@ -219,14 +194,6 @@ static void update_dst_buf_vars(struct i915_context *i915)
       i915->hardware_dirty |= I915_HW_STATIC;
    }
 
-   need_fixup = need_target_fixup(cbuf_surface, &fixup);
-   if (i915->current.target_fixup_format != need_fixup ||
-         i915->current.fixup_swizzle != fixup) {
-      i915->current.target_fixup_format = need_fixup;
-      i915->current.fixup_swizzle = fixup;
-      /* we also send a new program to make sure the fixup for RGBA surfaces happens */
-      i915->hardware_dirty |= I915_HW_PROGRAM;
-   }
 }
 
 struct i915_tracked_state i915_hw_dst_buf_vars = {
diff --git a/src/gallium/drivers/i915/i915_surface.c b/src/gallium/drivers/i915/i915_surface.c
index 3c717bccec3..e43284fa36f 100644
--- a/src/gallium/drivers/i915/i915_surface.c
+++ b/src/gallium/drivers/i915/i915_surface.c
@@ -349,6 +349,31 @@ i915_clear_depth_stencil_blitter(struct pipe_context *pipe,
  * Screen surface functions
  */
 
+static void i915_set_color_surface_swizzle(struct i915_surface *surf)
+{
+   const struct {
+      enum pipe_format format;
+      uint8_t color_swizzle[4];
+      uint32_t oc_swizzle;
+   } fixup_formats[] = {
+      { PIPE_FORMAT_R8G8B8A8_UNORM, {2, 1, 0, 3 }, 0x21030000 /* BGRA */},
+      { PIPE_FORMAT_R8G8B8X8_UNORM, {2, 1, 0, 3 }, 0x21030000 /* BGRX */},
+      { PIPE_FORMAT_L8_UNORM,       {0, 0, 0, 0 }, 0x00030000 /* RRRA */},
+      { PIPE_FORMAT_I8_UNORM,       {0, 0, 0, 0 }, 0x00030000 /* RRRA */},
+      { PIPE_FORMAT_A8_UNORM,       {3, 3, 3, 3 }, 0x33330000 /* AAAA */},
+   };
+
+   for (int i = 0; i < ARRAY_SIZE(fixup_formats); i++) {
+      if (fixup_formats[i].format == surf->templ.format) {
+         memcpy(surf->color_swizzle, fixup_formats[i].color_swizzle, sizeof(surf->color_swizzle));
+         surf->oc_swizzle = fixup_formats[i].oc_swizzle;
+         return;
+      }
+   }
+
+   for (int i = 0; i < 4; i++)
+      surf->color_swizzle[i] = i;
+}
 
 static struct pipe_surface *
 i915_create_surface_custom(struct pipe_context *ctx,
@@ -385,6 +410,8 @@ i915_create_surface_custom(struct pipe_context *ctx,
       surf->buf_info = BUF_3D_ID_DEPTH;
    } else {
       surf->buf_info = BUF_3D_ID_COLOR_BACK;
+
+      i915_set_color_surface_swizzle(surf);
    }
 
    surf->buf_info |= BUF_3D_PITCH(tex->stride); /* pitch in bytes */



More information about the mesa-commit mailing list