Mesa (main): lima: add more wrap modes

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Nov 16 23:13:17 UTC 2021


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

Author: Vasily Khoruzhick <anarsoul at gmail.com>
Date:   Wed Oct  6 07:16:33 2021 -0700

lima: add more wrap modes

Using 1 bit per wrap mode looked very suspicious and after some
experiments it turns out it's 3-bit enum.

Border color is also here, it sits right after depth field. For
some reason it uses 16 bit per channel just like for clear color in RSW

GL_CLAMP mode is broken for nearest filter just as on Midgard, so add
the same workaround - use GL_CLAMP_TO_EDGE for nearest filter.

Reviewed-by: Andreas Baierl <ichgeh at imkreisrum.de>
Signed-off-by: Vasily Khoruzhick <anarsoul at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13213>

---

 docs/drivers/lima.rst                   |  2 -
 src/gallium/drivers/lima/lima_job.c     |  6 +--
 src/gallium/drivers/lima/lima_parser.c  | 42 ++++++----------
 src/gallium/drivers/lima/lima_parser.h  | 19 +++++++
 src/gallium/drivers/lima/lima_texture.c | 89 ++++++++++++++++-----------------
 src/gallium/drivers/lima/lima_texture.h | 32 ++++++------
 6 files changed, 98 insertions(+), 92 deletions(-)

diff --git a/docs/drivers/lima.rst b/docs/drivers/lima.rst
index 04b87772f6a..91c16c0c3c5 100644
--- a/docs/drivers/lima.rst
+++ b/docs/drivers/lima.rst
@@ -110,8 +110,6 @@ Here are some known caveats in OpenGL support:
 
 - ``glPolygonMode()`` with ``GL_LINE`` is not supported. This is not part of
   OpenGL ES 2.0 and so it is not possible to reverse engineer.
-- Texture wrapping with ``GL_CLAMP_TO_BORDER`` is not supported. This is not
-  part of OpenGL ES 2.0 and so it is not possible to reverse engineer.
 
 - Precision limitations in fragment shaders:
 
diff --git a/src/gallium/drivers/lima/lima_job.c b/src/gallium/drivers/lima/lima_job.c
index dfbe67e1062..c3bb29c50ee 100644
--- a/src/gallium/drivers/lima/lima_job.c
+++ b/src/gallium/drivers/lima/lima_job.c
@@ -398,9 +398,9 @@ lima_pack_reload_plbu_cmd(struct lima_job *job, struct pipe_surface *psurf)
    td->sampler_dim = LIMA_SAMPLER_DIM_2D;
    td->min_img_filter_nearest = 1;
    td->mag_img_filter_nearest = 1;
-   td->wrap_s_clamp_to_edge = 1;
-   td->wrap_t_clamp_to_edge = 1;
-   td->wrap_r_clamp_to_edge = 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;
diff --git a/src/gallium/drivers/lima/lima_parser.c b/src/gallium/drivers/lima/lima_parser.c
index 6a871170b29..3e69daee1b2 100644
--- a/src/gallium/drivers/lima/lima_parser.c
+++ b/src/gallium/drivers/lima/lima_parser.c
@@ -728,10 +728,11 @@ parse_texture(FILE *fp, uint32_t *data, uint32_t start, uint32_t offset)
    fprintf(fp, "\t stride: 0x%x (%d)\n", desc->stride, desc->stride);
    fprintf(fp, "\t unknown_0_2: 0x%x (%d)\n", desc->unknown_0_2, desc->unknown_0_2);
 
-   /* Word 1 - 3 */
-   fprintf(fp, "/* 0x%08x (0x%08x) */\t0x%08x 0x%08x 0x%08x\n",
-           start + i * 4, i * 4, *(&data[i + offset]), *(&data[i + 1 + offset]), *(&data[i + 2 + offset]));
-   i += 3;
+   /* Word 1 - 5 */
+   fprintf(fp, "/* 0x%08x (0x%08x) */\t0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
+           start + i * 4, i * 4, *(&data[i + offset]), *(&data[i + 1 + offset]),
+           *(&data[i + 2 + offset]), *(&data[i + 3 + offset]), *(&data[i + 4 + offset]));
+   i += 5;
    fprintf(fp, "\t unknown_1_1: 0x%x (%d)\n", desc->unknown_1_1, desc->unknown_1_1);
    fprintf(fp, "\t unnorm_coords: 0x%x (%d)\n", desc->unnorm_coords, desc->unnorm_coords);
    fprintf(fp, "\t unknown_1_2: 0x%x (%d)\n", desc->unknown_1_2, desc->unknown_1_2);
@@ -745,31 +746,20 @@ parse_texture(FILE *fp, uint32_t *data, uint32_t start, uint32_t offset)
    fprintf(fp, "\t min_mipfilter_2: 0x%x (%d)\n", desc->min_mipfilter_2, desc->min_mipfilter_2);
    fprintf(fp, "\t min_img_filter_nearest: 0x%x (%d)\n", desc->min_img_filter_nearest, desc->min_img_filter_nearest);
    fprintf(fp, "\t mag_img_filter_nearest: 0x%x (%d)\n", desc->mag_img_filter_nearest, desc->mag_img_filter_nearest);
-   fprintf(fp, "\t wrap_s_clamp_to_edge: 0x%x (%d)\n", desc->wrap_s_clamp_to_edge, desc->wrap_s_clamp_to_edge);
-   fprintf(fp, "\t wrap_s_clamp: 0x%x (%d)\n", desc->wrap_s_clamp, desc->wrap_s_clamp);
-   fprintf(fp, "\t wrap_s_mirror_repeat: 0x%x (%d)\n", desc->wrap_s_mirror_repeat, desc->wrap_s_mirror_repeat);
-   fprintf(fp, "\t wrap_t_clamp_to_edge: 0x%x (%d)\n", desc->wrap_t_clamp_to_edge, desc->wrap_t_clamp_to_edge);
-   fprintf(fp, "\t wrap_t_clamp: 0x%x (%d)\n", desc->wrap_t_clamp, desc->wrap_t_clamp);
-   fprintf(fp, "\t wrap_t_mirror_repeat: 0x%x (%d)\n", desc->wrap_t_mirror_repeat, desc->wrap_t_mirror_repeat);
-   fprintf(fp, "\t wrap_r_clamp_to_edge: 0x%x (%d)\n", desc->wrap_r_clamp_to_edge, desc->wrap_r_clamp_to_edge);
-   fprintf(fp, "\t wrap_r_clamp: 0x%x (%d)\n", desc->wrap_r_clamp, desc->wrap_r_clamp);
-   fprintf(fp, "\t wrap_r_mirror_repeat: 0x%x (%d)\n", desc->wrap_r_mirror_repeat, desc->wrap_r_mirror_repeat);
+   fprintf(fp, "\t wrap_s: %d (%s)\n", desc->wrap_s,
+           lima_get_wrap_mode_string(desc->wrap_s));
+   fprintf(fp, "\t wrap_t: %d (%s)\n", desc->wrap_t,
+           lima_get_wrap_mode_string(desc->wrap_t));
+   fprintf(fp, "\t wrap_r: %d (%s)\n", desc->wrap_r,
+           lima_get_wrap_mode_string(desc->wrap_r));
    fprintf(fp, "\t width: 0x%x (%d)\n", desc->width, desc->width);
    fprintf(fp, "\t height: 0x%x (%d)\n", desc->height, desc->height);
    fprintf(fp, "\t depth: 0x%x (%d)\n", desc->depth, desc->depth);
-   fprintf(fp, "\t unknown_3_1: 0x%x (%d)\n", desc->unknown_3_1, desc->unknown_3_1);
-
-   /* Word 4 */
-   fprintf(fp, "/* 0x%08x (0x%08x) */\t0x%08x\n",
-           start + i * 4, i * 4, *(&data[i + offset]));
-   i++;
-   fprintf(fp, "\t unknown_4: 0x%x (%d)\n", desc->unknown_4, desc->unknown_4);
-
-   /* Word 5 */
-   fprintf(fp, "/* 0x%08x (0x%08x) */\t0x%08x\n",
-           start + i * 4, i * 4, *(&data[i + offset]));
-   i++;
-   fprintf(fp, "\t unknown_5: 0x%x (%d)\n", desc->unknown_5, desc->unknown_5);
+   fprintf(fp, "\t border_red: 0x%x (%d)\n", desc->border_red, desc->border_red);
+   fprintf(fp, "\t border_green: 0x%x (%d)\n", desc->border_green, desc->border_green);
+   fprintf(fp, "\t border_blue: 0x%x (%d)\n", desc->border_blue, desc->border_blue);
+   fprintf(fp, "\t border_alpha: 0x%x (%d)\n", desc->border_alpha, desc->border_alpha);
+   fprintf(fp, "\t unknown_5_1: 0x%x (%d)\n", desc->unknown_5_1, desc->unknown_5_1);
 
    /* Word 6 - */
    fprintf(fp, "/* 0x%08x (0x%08x) */",
diff --git a/src/gallium/drivers/lima/lima_parser.h b/src/gallium/drivers/lima/lima_parser.h
index d592c9f8618..dc99d49164b 100644
--- a/src/gallium/drivers/lima/lima_parser.h
+++ b/src/gallium/drivers/lima/lima_parser.h
@@ -86,6 +86,17 @@ static const char *PIPE_BLENDFACTOR_STRING[] = {
 
 };
 
+static const char *LIMA_WRAP_MODE_STRING[] = {
+   "TEX_WRAP_REPEAT",                  /* 0 */
+   "TEX_WRAP_CLAMP_TO_EDGE",           /* 1 */
+   "TEX_WRAP_CLAMP",                   /* 2 */
+   "TEX_WRAP_CLAMP_TO_BORDER",         /* 3 */
+   "TEX_WRAP_MIRROR_REPEAT",           /* 4 */
+   "TEX_WRAP_MIRROR_CLAMP_TO_EDGE",    /* 5 */
+   "TEX_WRAP_MIRROR_CLAMP",            /* 6 */
+   "TEX_WRAP_MIRROR_CLAMP_TO_BORDER",  /* 7 */
+};
+
 static inline const char
 *lima_get_compare_func_string(int func) {
    if ((func >= 0) && (func <= 7))
@@ -118,6 +129,14 @@ static inline const char
       return "UNKNOWN";
 }
 
+static inline const char
+*lima_get_wrap_mode_string(int mode) {
+   if ((mode >= 0) && (mode <= 7))
+      return LIMA_WRAP_MODE_STRING[mode];
+   else
+      return "UNKNOWN";
+}
+
 void lima_parse_shader(FILE *fp, uint32_t *data, int size, bool is_frag);
 void lima_parse_vs(FILE *fp, uint32_t *data, int size, uint32_t start);
 void lima_parse_plbu(FILE *fp, uint32_t *data, int size, uint32_t start);
diff --git a/src/gallium/drivers/lima/lima_texture.c b/src/gallium/drivers/lima/lima_texture.c
index 59e30ac3df3..1ec03dea9ff 100644
--- a/src/gallium/drivers/lima/lima_texture.c
+++ b/src/gallium/drivers/lima/lima_texture.c
@@ -115,6 +115,37 @@ lima_texture_desc_set_res(struct lima_context *ctx, lima_tex_desc *desc,
    }
 }
 
+static unsigned
+pipe_wrap_to_lima(unsigned pipe_wrap, bool using_nearest)
+{
+   switch (pipe_wrap) {
+   case PIPE_TEX_WRAP_REPEAT:
+      return LIMA_TEX_WRAP_REPEAT;
+   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
+      return LIMA_TEX_WRAP_CLAMP_TO_EDGE;
+   case PIPE_TEX_WRAP_CLAMP:
+      if (using_nearest)
+         return LIMA_TEX_WRAP_CLAMP_TO_EDGE;
+      else
+         return LIMA_TEX_WRAP_CLAMP;
+   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
+      return LIMA_TEX_WRAP_CLAMP_TO_BORDER;
+   case PIPE_TEX_WRAP_MIRROR_REPEAT:
+      return LIMA_TEX_WRAP_MIRROR_REPEAT;
+   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
+      return LIMA_TEX_WRAP_MIRROR_CLAMP_TO_EDGE;
+   case PIPE_TEX_WRAP_MIRROR_CLAMP:
+      if (using_nearest)
+         return LIMA_TEX_WRAP_MIRROR_CLAMP_TO_EDGE;
+      else
+         return LIMA_TEX_WRAP_MIRROR_CLAMP;
+   case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
+      return LIMA_TEX_WRAP_MIRROR_CLAMP_TO_BORDER;
+   default:
+      return LIMA_TEX_WRAP_REPEAT;
+   }
+}
+
 static void
 lima_update_tex_desc(struct lima_context *ctx, struct lima_sampler_state *sampler,
                      struct lima_sampler_view *texture, void *pdesc,
@@ -199,55 +230,19 @@ lima_update_tex_desc(struct lima_context *ctx, struct lima_sampler_state *sample
       break;
    }
 
-   /* Only clamp, clamp to edge, repeat and mirror repeat are supported */
-   switch (sampler->base.wrap_s) {
-   case PIPE_TEX_WRAP_CLAMP:
-      desc->wrap_s_clamp = 1;
-      break;
-   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
-   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
-      desc->wrap_s_clamp_to_edge = 1;
-      break;
-   case PIPE_TEX_WRAP_MIRROR_REPEAT:
-      desc->wrap_s_mirror_repeat = 1;
-      break;
-   case PIPE_TEX_WRAP_REPEAT:
-   default:
-      break;
-   }
+   /* Panfrost mentions that GL_CLAMP is broken for NEAREST filter on Midgard,
+    * looks like it also broken on Utgard, since it fails in piglit
+    */
+   bool using_nearest = sampler->base.min_img_filter == PIPE_TEX_FILTER_NEAREST;
 
-   /* Only clamp, clamp to edge, repeat and mirror repeat are supported */
-   switch (sampler->base.wrap_t) {
-   case PIPE_TEX_WRAP_CLAMP:
-      desc->wrap_t_clamp = 1;
-      break;
-   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
-   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
-      desc->wrap_t_clamp_to_edge = 1;
-      break;
-   case PIPE_TEX_WRAP_MIRROR_REPEAT:
-      desc->wrap_t_mirror_repeat = 1;
-      break;
-   case PIPE_TEX_WRAP_REPEAT:
-   default:
-      break;
-   }
+   desc->wrap_s = pipe_wrap_to_lima(sampler->base.wrap_s, using_nearest);
+   desc->wrap_t = pipe_wrap_to_lima(sampler->base.wrap_t, using_nearest);
+   desc->wrap_r = pipe_wrap_to_lima(sampler->base.wrap_r, using_nearest);
 
-   switch (sampler->base.wrap_r) {
-   case PIPE_TEX_WRAP_CLAMP:
-      desc->wrap_r_clamp = 1;
-      break;
-   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
-   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
-      desc->wrap_r_clamp_to_edge = 1;
-      break;
-   case PIPE_TEX_WRAP_MIRROR_REPEAT:
-      desc->wrap_r_mirror_repeat = 1;
-      break;
-   case PIPE_TEX_WRAP_REPEAT:
-   default:
-      break;
-   }
+   desc->border_red = float_to_ushort(sampler->base.border_color.f[0]);
+   desc->border_green = float_to_ushort(sampler->base.border_color.f[1]);
+   desc->border_blue = float_to_ushort(sampler->base.border_color.f[2]);
+   desc->border_alpha = float_to_ushort(sampler->base.border_color.f[3]);
 
    if (desc->min_img_filter_nearest && desc->mag_img_filter_nearest &&
        desc->min_mipfilter_2 == 0 &&
diff --git a/src/gallium/drivers/lima/lima_texture.h b/src/gallium/drivers/lima/lima_texture.h
index f95dfdfbcc9..6d8dd4d2772 100644
--- a/src/gallium/drivers/lima/lima_texture.h
+++ b/src/gallium/drivers/lima/lima_texture.h
@@ -31,6 +31,15 @@
 #define LIMA_SAMPLER_DIM_2D   1
 #define LIMA_SAMPLER_DIM_3D   2
 
+#define LIMA_TEX_WRAP_REPEAT                 0
+#define LIMA_TEX_WRAP_CLAMP_TO_EDGE          1
+#define LIMA_TEX_WRAP_CLAMP                  2
+#define LIMA_TEX_WRAP_CLAMP_TO_BORDER        3
+#define LIMA_TEX_WRAP_MIRROR_REPEAT          4
+#define LIMA_TEX_WRAP_MIRROR_CLAMP_TO_EDGE   5
+#define LIMA_TEX_WRAP_MIRROR_CLAMP           6
+#define LIMA_TEX_WRAP_MIRROR_CLAMP_TO_BORDER 7
+
 typedef struct __attribute__((__packed__)) {
    /* Word 0 */
    uint32_t format : 6;
@@ -54,25 +63,20 @@ typedef struct __attribute__((__packed__)) {
    uint32_t min_mipfilter_2: 2; /* 0x3 for linear, 0x0 for nearest */
    uint32_t min_img_filter_nearest: 1;
    uint32_t mag_img_filter_nearest: 1;
-   uint32_t wrap_s_clamp_to_edge: 1;
-   uint32_t wrap_s_clamp: 1;
-   uint32_t wrap_s_mirror_repeat: 1;
-   uint32_t wrap_t_clamp_to_edge: 1;
-   uint32_t wrap_t_clamp: 1;
-   uint32_t wrap_t_mirror_repeat: 1;
-   uint32_t wrap_r_clamp_to_edge: 1;
-   uint32_t wrap_r_clamp: 1;
-   uint32_t wrap_r_mirror_repeat: 1;
+   uint32_t wrap_s: 3;
+   uint32_t wrap_t: 3;
+   uint32_t wrap_r: 3;
    uint32_t width: 13;
    uint32_t height: 13;
    uint32_t depth: 13;
-   uint32_t unknown_3_1: 3;
 
-   /* Word 4 */
-   uint32_t unknown_4;
+   uint32_t border_red: 16;
+   uint32_t border_green: 16;
+   uint32_t border_blue: 16;
+   uint32_t border_alpha: 16;
 
-   /* Word 5 */
-   uint32_t unknown_5;
+   /* Word 5 (last 3 bits) */
+   uint32_t unknown_5_1: 3;
 
    /* Word 6-15 */
    /* layout is in va[0] bit 13-14 */



More information about the mesa-commit mailing list