From: Nicolai Hähnle <nicolai.haeh...@amd.com>

The hardware does this automatically for unorm formats, but we need to
do it manually for unorm depth formats that have been upgraded to
Z32_FLOAT.

Fixes 
dEQP-GLES31.functional.texture.border_clamp.range_clamp.nearest_unorm_depth
and others.

Fixes: d4d9ec55c589 ("radeonsi: implement TC-compatible HTILE")
---
 src/gallium/drivers/radeonsi/si_state.c | 119 ++++++++++++++++----------------
 1 file changed, 60 insertions(+), 59 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_state.c 
b/src/gallium/drivers/radeonsi/si_state.c
index 551bb17503c..2a27ea0c503 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -3888,96 +3888,85 @@ static void si_sampler_view_destroy(struct pipe_context 
*ctx,
 
 static bool wrap_mode_uses_border_color(unsigned wrap, bool linear_filter)
 {
        return wrap == PIPE_TEX_WRAP_CLAMP_TO_BORDER ||
               wrap == PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER ||
               (linear_filter &&
                (wrap == PIPE_TEX_WRAP_CLAMP ||
                 wrap == PIPE_TEX_WRAP_MIRROR_CLAMP));
 }
 
-static bool sampler_state_needs_border_color(const struct pipe_sampler_state 
*state)
+static uint32_t si_translate_border_color(struct si_context *sctx,
+                                         const struct pipe_sampler_state 
*state,
+                                         const union pipe_color_union *color)
 {
        bool linear_filter = state->min_img_filter != PIPE_TEX_FILTER_NEAREST ||
                             state->mag_img_filter != PIPE_TEX_FILTER_NEAREST;
 
-       return (state->border_color.ui[0] || state->border_color.ui[1] ||
-               state->border_color.ui[2] || state->border_color.ui[3]) &&
-              (wrap_mode_uses_border_color(state->wrap_s, linear_filter) ||
-               wrap_mode_uses_border_color(state->wrap_t, linear_filter) ||
-               wrap_mode_uses_border_color(state->wrap_r, linear_filter));
+       if ((color->f[0] == 0 && color->f[1] == 0 &&
+            color->f[2] == 0 && color->f[3] == 0) ||
+           (!wrap_mode_uses_border_color(state->wrap_s, linear_filter) &&
+            !wrap_mode_uses_border_color(state->wrap_t, linear_filter) &&
+            !wrap_mode_uses_border_color(state->wrap_r, linear_filter)))
+               return 
S_008F3C_BORDER_COLOR_TYPE(V_008F3C_SQ_TEX_BORDER_COLOR_TRANS_BLACK);
+
+       if (color->f[0] == 0 && color->f[1] == 0 &&
+           color->f[2] == 0 && color->f[3] == 1)
+               return 
S_008F3C_BORDER_COLOR_TYPE(V_008F3C_SQ_TEX_BORDER_COLOR_OPAQUE_BLACK);
+       if (color->f[0] == 1 && color->f[1] == 1 &&
+           color->f[2] == 1 && color->f[3] == 1)
+               return 
S_008F3C_BORDER_COLOR_TYPE(V_008F3C_SQ_TEX_BORDER_COLOR_OPAQUE_WHITE);
+
+       int i;
+
+       /* Check if the border has been uploaded already. */
+       for (i = 0; i < sctx->border_color_count; i++)
+               if (memcmp(&sctx->border_color_table[i], color,
+                          sizeof(*color)) == 0)
+                       break;
+
+       if (i >= SI_MAX_BORDER_COLORS) {
+               /* Getting 4096 unique border colors is very unlikely. */
+               fprintf(stderr, "radeonsi: The border color table is full. "
+                       "Any new border colors will be just black. "
+                       "Please file a bug.\n");
+               return 
S_008F3C_BORDER_COLOR_TYPE(V_008F3C_SQ_TEX_BORDER_COLOR_TRANS_BLACK);
+       }
+
+       if (i == sctx->border_color_count) {
+               /* Upload a new border color. */
+               memcpy(&sctx->border_color_table[i], color,
+                      sizeof(*color));
+               util_memcpy_cpu_to_le32(&sctx->border_color_map[i],
+                                       color, sizeof(*color));
+               sctx->border_color_count++;
+       }
+
+       return S_008F3C_BORDER_COLOR_PTR(i) |
+              
S_008F3C_BORDER_COLOR_TYPE(V_008F3C_SQ_TEX_BORDER_COLOR_REGISTER);
 }
 
 static void *si_create_sampler_state(struct pipe_context *ctx,
                                     const struct pipe_sampler_state *state)
 {
        struct si_context *sctx = (struct si_context *)ctx;
        struct r600_common_screen *rscreen = sctx->b.screen;
        struct si_sampler_state *rstate = CALLOC_STRUCT(si_sampler_state);
-       unsigned border_color_type, border_color_index = 0;
        unsigned max_aniso = rscreen->force_aniso >= 0 ? rscreen->force_aniso
                                                       : state->max_anisotropy;
        unsigned max_aniso_ratio = r600_tex_aniso_filter(max_aniso);
+       union pipe_color_union clamped_border_color;
 
        if (!rstate) {
                return NULL;
        }
 
-       if (!sampler_state_needs_border_color(state))
-               border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_TRANS_BLACK;
-       else if (state->border_color.f[0] == 0 &&
-                state->border_color.f[1] == 0 &&
-                state->border_color.f[2] == 0 &&
-                state->border_color.f[3] == 0)
-               border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_TRANS_BLACK;
-       else if (state->border_color.f[0] == 0 &&
-                state->border_color.f[1] == 0 &&
-                state->border_color.f[2] == 0 &&
-                state->border_color.f[3] == 1)
-               border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_OPAQUE_BLACK;
-       else if (state->border_color.f[0] == 1 &&
-                state->border_color.f[1] == 1 &&
-                state->border_color.f[2] == 1 &&
-                state->border_color.f[3] == 1)
-               border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_OPAQUE_WHITE;
-       else {
-               int i;
-
-               border_color_type = V_008F3C_SQ_TEX_BORDER_COLOR_REGISTER;
-
-               /* Check if the border has been uploaded already. */
-               for (i = 0; i < sctx->border_color_count; i++)
-                       if (memcmp(&sctx->border_color_table[i], 
&state->border_color,
-                                  sizeof(state->border_color)) == 0)
-                               break;
-
-               if (i >= SI_MAX_BORDER_COLORS) {
-                       /* Getting 4096 unique border colors is very unlikely. 
*/
-                       fprintf(stderr, "radeonsi: The border color table is 
full. "
-                               "Any new border colors will be just black. "
-                               "Please file a bug.\n");
-                       border_color_type = 
V_008F3C_SQ_TEX_BORDER_COLOR_TRANS_BLACK;
-               } else {
-                       if (i == sctx->border_color_count) {
-                               /* Upload a new border color. */
-                               memcpy(&sctx->border_color_table[i], 
&state->border_color,
-                                      sizeof(state->border_color));
-                               
util_memcpy_cpu_to_le32(&sctx->border_color_map[i],
-                                                       &state->border_color,
-                                                       
sizeof(state->border_color));
-                               sctx->border_color_count++;
-                       }
-
-                       border_color_index = i;
-               }
-       }
-
 #ifdef DEBUG
        rstate->magic = SI_SAMPLER_STATE_MAGIC;
 #endif
        rstate->val[0] = (S_008F30_CLAMP_X(si_tex_wrap(state->wrap_s)) |
                          S_008F30_CLAMP_Y(si_tex_wrap(state->wrap_t)) |
                          S_008F30_CLAMP_Z(si_tex_wrap(state->wrap_r)) |
                          S_008F30_MAX_ANISO_RATIO(max_aniso_ratio) |
                          
S_008F30_DEPTH_COMPARE_FUNC(si_tex_compare(state->compare_func)) |
                          
S_008F30_FORCE_UNNORMALIZED(!state->normalized_coords) |
                          S_008F30_ANISO_THRESHOLD(max_aniso_ratio >> 1) |
@@ -3988,25 +3977,37 @@ static void *si_create_sampler_state(struct 
pipe_context *ctx,
                          S_008F34_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 
15), 8)) |
                          S_008F34_PERF_MIP(max_aniso_ratio ? max_aniso_ratio + 
6 : 0));
        rstate->val[2] = (S_008F38_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 
16), 8)) |
                          
S_008F38_XY_MAG_FILTER(eg_tex_filter(state->mag_img_filter, max_aniso)) |
                          
S_008F38_XY_MIN_FILTER(eg_tex_filter(state->min_img_filter, max_aniso)) |
                          
S_008F38_MIP_FILTER(si_tex_mipfilter(state->min_mip_filter)) |
                          S_008F38_MIP_POINT_PRECLAMP(0) |
                          S_008F38_DISABLE_LSB_CEIL(sctx->b.chip_class <= VI) |
                          S_008F38_FILTER_PREC_FIX(1) |
                          S_008F38_ANISO_OVERRIDE(sctx->b.chip_class >= VI));
-       rstate->val[3] = S_008F3C_BORDER_COLOR_PTR(border_color_index) |
-                        S_008F3C_BORDER_COLOR_TYPE(border_color_type);
+       rstate->val[3] = si_translate_border_color(sctx, state, 
&state->border_color);
 
+       /* Create sampler resource for upgraded depth textures. */
        memcpy(rstate->upgraded_depth_val, rstate->val, sizeof(rstate->val));
-       rstate->upgraded_depth_val[3] |= S_008F3C_UPGRADED_DEPTH(1);
+
+       for (unsigned i = 0; i < 4; ++i) {
+               /* Use channel 0 on purpose, so that we can use OPAQUE_WHITE
+                * when the border color is 1.0. */
+               clamped_border_color.f[i] = CLAMP(state->border_color.f[0], 0, 
1);
+       }
+
+       if (memcmp(&state->border_color, &clamped_border_color, 
sizeof(clamped_border_color)) == 0)
+               rstate->upgraded_depth_val[3] |= S_008F3C_UPGRADED_DEPTH(1);
+       else
+               rstate->upgraded_depth_val[3] =
+                       si_translate_border_color(sctx, state, 
&clamped_border_color) |
+                       S_008F3C_UPGRADED_DEPTH(1);
 
        return rstate;
 }
 
 static void si_set_sample_mask(struct pipe_context *ctx, unsigned sample_mask)
 {
        struct si_context *sctx = (struct si_context *)ctx;
 
        if (sctx->sample_mask.sample_mask == (uint16_t)sample_mask)
                return;
-- 
2.11.0

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to