Mesa (master): panfrost: Fix CLAMP wrap mode

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sun Dec 20 02:42:27 UTC 2020


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

Author: Icecream95 <ixn at disroot.org>
Date:   Sun Dec 20 00:21:58 2020 +1300

panfrost: Fix CLAMP wrap mode

MALI_WRAP_MODE_CLAMP doesn't work fully on either GPU generation, so
use other wrap modes instead in some cases.

With nearest filtering, Midgard only clamps to the edge for two of the
edges, and uses the border colour for the other two. Using the clamp
mode on Bifrost causes broken rendering and/or GPU faults.

Fixes piglit test "texwrap" on both Midgard and Bifrost, and fixes
Chromium B.S.U. rendering on Bifrost.

Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8176>

---

 src/gallium/drivers/panfrost/pan_cmdstream.c | 32 ++++++++++++++++++++--------
 1 file changed, 23 insertions(+), 9 deletions(-)

diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c
index 996aba903f8..183dfff5962 100644
--- a/src/gallium/drivers/panfrost/pan_cmdstream.c
+++ b/src/gallium/drivers/panfrost/pan_cmdstream.c
@@ -116,15 +116,25 @@ panfrost_get_index_buffer_bounded(struct panfrost_context *ctx,
 }
 
 static unsigned
-translate_tex_wrap(enum pipe_tex_wrap w)
+translate_tex_wrap(enum pipe_tex_wrap w, bool supports_clamp, bool using_nearest)
 {
+        /* Bifrost doesn't support the GL_CLAMP wrap mode, so instead use
+         * CLAMP_TO_EDGE and CLAMP_TO_BORDER. On Midgard, CLAMP is broken for
+         * nearest filtering, so use CLAMP_TO_EDGE in that case. */
+
         switch (w) {
         case PIPE_TEX_WRAP_REPEAT: return MALI_WRAP_MODE_REPEAT;
-        case PIPE_TEX_WRAP_CLAMP: return MALI_WRAP_MODE_CLAMP;
+        case PIPE_TEX_WRAP_CLAMP:
+                return using_nearest ? MALI_WRAP_MODE_CLAMP_TO_EDGE :
+                     (supports_clamp ? MALI_WRAP_MODE_CLAMP :
+                                       MALI_WRAP_MODE_CLAMP_TO_BORDER);
         case PIPE_TEX_WRAP_CLAMP_TO_EDGE: return MALI_WRAP_MODE_CLAMP_TO_EDGE;
         case PIPE_TEX_WRAP_CLAMP_TO_BORDER: return MALI_WRAP_MODE_CLAMP_TO_BORDER;
         case PIPE_TEX_WRAP_MIRROR_REPEAT: return MALI_WRAP_MODE_MIRRORED_REPEAT;
-        case PIPE_TEX_WRAP_MIRROR_CLAMP: return MALI_WRAP_MODE_MIRRORED_CLAMP;
+        case PIPE_TEX_WRAP_MIRROR_CLAMP:
+                return using_nearest ? MALI_WRAP_MODE_MIRRORED_CLAMP_TO_EDGE :
+                     (supports_clamp ? MALI_WRAP_MODE_MIRRORED_CLAMP :
+                                       MALI_WRAP_MODE_MIRRORED_CLAMP_TO_BORDER);
         case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: return MALI_WRAP_MODE_MIRRORED_CLAMP_TO_EDGE;
         case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: return MALI_WRAP_MODE_MIRRORED_CLAMP_TO_BORDER;
         default: unreachable("Invalid wrap");
@@ -158,6 +168,8 @@ pan_pipe_to_mipmode(enum pipe_tex_mipfilter f)
 void panfrost_sampler_desc_init(const struct pipe_sampler_state *cso,
                                 struct mali_midgard_sampler_packed *hw)
 {
+        bool using_nearest = cso->min_img_filter == PIPE_TEX_MIPFILTER_NEAREST;
+
         pan_pack(hw, MIDGARD_SAMPLER, cfg) {
                 cfg.magnify_nearest = cso->mag_img_filter == PIPE_TEX_FILTER_NEAREST;
                 cfg.minify_nearest = cso->min_img_filter == PIPE_TEX_FILTER_NEAREST;
@@ -178,9 +190,9 @@ void panfrost_sampler_desc_init(const struct pipe_sampler_state *cso,
                         cfg.minimum_lod + 1 :
                         FIXED_16(cso->max_lod, false);
 
-                cfg.wrap_mode_s = translate_tex_wrap(cso->wrap_s);
-                cfg.wrap_mode_t = translate_tex_wrap(cso->wrap_t);
-                cfg.wrap_mode_r = translate_tex_wrap(cso->wrap_r);
+                cfg.wrap_mode_s = translate_tex_wrap(cso->wrap_s, true, using_nearest);
+                cfg.wrap_mode_t = translate_tex_wrap(cso->wrap_t, true, using_nearest);
+                cfg.wrap_mode_r = translate_tex_wrap(cso->wrap_r, true, using_nearest);
 
                 cfg.compare_function = panfrost_sampler_compare_func(cso);
                 cfg.seamless_cube_map = cso->seamless_cube_map;
@@ -195,6 +207,8 @@ void panfrost_sampler_desc_init(const struct pipe_sampler_state *cso,
 void panfrost_sampler_desc_init_bifrost(const struct pipe_sampler_state *cso,
                                         struct mali_bifrost_sampler_packed *hw)
 {
+        bool using_nearest = cso->min_img_filter == PIPE_TEX_MIPFILTER_NEAREST;
+
         pan_pack(hw, BIFROST_SAMPLER, cfg) {
                 cfg.point_sample_magnify = cso->mag_img_filter == PIPE_TEX_FILTER_NEAREST;
                 cfg.point_sample_minify = cso->min_img_filter == PIPE_TEX_FILTER_NEAREST;
@@ -205,9 +219,9 @@ void panfrost_sampler_desc_init_bifrost(const struct pipe_sampler_state *cso,
                 cfg.minimum_lod = FIXED_16(cso->min_lod, false);
                 cfg.maximum_lod = FIXED_16(cso->max_lod, false);
 
-                cfg.wrap_mode_s = translate_tex_wrap(cso->wrap_s);
-                cfg.wrap_mode_t = translate_tex_wrap(cso->wrap_t);
-                cfg.wrap_mode_r = translate_tex_wrap(cso->wrap_r);
+                cfg.wrap_mode_s = translate_tex_wrap(cso->wrap_s, false, using_nearest);
+                cfg.wrap_mode_t = translate_tex_wrap(cso->wrap_t, false, using_nearest);
+                cfg.wrap_mode_r = translate_tex_wrap(cso->wrap_r, false, using_nearest);
 
                 cfg.compare_function = panfrost_sampler_compare_func(cso);
                 cfg.seamless_cube_map = cso->seamless_cube_map;



More information about the mesa-commit mailing list