diff options
-rw-r--r-- | src/gallium/drivers/radeonsi/si_descriptors.c | 37 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_pipe.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state.c | 50 |
3 files changed, 60 insertions, 29 deletions
diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index fbb72d900b1..1afdfbe4f69 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -379,6 +379,20 @@ void si_set_mutable_tex_desc_fields(struct si_screen *sscreen, } } +static void si_set_sampler_state_desc(struct si_sampler_state *sstate, + struct si_sampler_view *sview, + struct r600_texture *tex, + uint32_t *desc) +{ + if (sview && sview->is_integer) + memcpy(desc, sstate->integer_val, 4*4); + else if (tex && tex->upgraded_depth && + (!sview || !sview->is_stencil_sampler)) + memcpy(desc, sstate->upgraded_depth_val, 4*4); + else + memcpy(desc, sstate->val, 4*4); +} + static void si_set_sampler_view_desc(struct si_context *sctx, struct si_sampler_view *sview, struct si_sampler_state *sstate, @@ -422,13 +436,10 @@ static void si_set_sampler_view_desc(struct si_context *sctx, /* Disable FMASK and bind sampler state in [12:15]. */ memcpy(desc + 8, null_texture_descriptor, 4*4); - if (sstate) { - if (!is_buffer && rtex->upgraded_depth && - !sview->is_stencil_sampler) - memcpy(desc + 12, sstate->upgraded_depth_val, 4*4); - else - memcpy(desc + 12, sstate->val, 4*4); - } + if (sstate) + si_set_sampler_state_desc(sstate, sview, + is_buffer ? NULL : rtex, + desc + 12); } } @@ -470,8 +481,8 @@ static void si_set_sampler_view(struct si_context *sctx, memcpy(desc + 8, null_texture_descriptor, 4*4); /* Re-set the sampler state if we are transitioning from FMASK. */ if (views->sampler_states[slot]) - memcpy(desc + 12, - views->sampler_states[slot]->val, 4*4); + si_set_sampler_state_desc(views->sampler_states[slot], NULL, NULL, + desc + 12); views->enabled_mask &= ~(1u << slot); } @@ -862,12 +873,8 @@ static void si_bind_sampler_states(struct pipe_context *ctx, if (tex && tex->fmask.size) continue; - if (tex && tex->upgraded_depth && !sview->is_stencil_sampler) - memcpy(desc->list + desc_slot * 16 + 12, - sstates[i]->upgraded_depth_val, 4*4); - else - memcpy(desc->list + desc_slot * 16 + 12, - sstates[i]->val, 4*4); + si_set_sampler_state_desc(sstates[i], sview, tex, + desc->list + desc_slot * 16 + 12); sctx->descriptors_dirty |= 1u << si_sampler_and_image_descriptors_idx(shader); } diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 80f38ea29bb..46c89e2f38a 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -157,6 +157,7 @@ struct si_sampler_view { ubyte base_level; ubyte block_width; bool is_stencil_sampler; + bool is_integer; bool dcc_incompatible; }; @@ -167,6 +168,7 @@ struct si_sampler_state { unsigned magic; #endif uint32_t val[4]; + uint32_t integer_val[4]; uint32_t upgraded_depth_val[4]; }; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 1463d3c9ca1..e82ca6a6946 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -3861,6 +3861,12 @@ si_create_sampler_view_custom(struct pipe_context *ctx, width, height, depth, view->state, view->fmask_state); + unsigned num_format = G_008F14_NUM_FORMAT_GFX6(view->state[1]); + view->is_integer = + num_format == V_008F14_IMG_NUM_FORMAT_USCALED || + num_format == V_008F14_IMG_NUM_FORMAT_SSCALED || + num_format == V_008F14_IMG_NUM_FORMAT_UINT || + num_format == V_008F14_IMG_NUM_FORMAT_SINT; view->base_level_info = &surflevel[base_level]; view->base_level = base_level; view->block_width = util_format_get_blockwidth(pipe_format); @@ -3897,24 +3903,36 @@ static bool wrap_mode_uses_border_color(unsigned wrap, bool linear_filter) static uint32_t si_translate_border_color(struct si_context *sctx, const struct pipe_sampler_state *state, - const union pipe_color_union *color) + const union pipe_color_union *color, + bool is_integer) { bool linear_filter = state->min_img_filter != PIPE_TEX_FILTER_NEAREST || state->mag_img_filter != PIPE_TEX_FILTER_NEAREST; - 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))) + if (!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); +#define simple_border_types(elt) \ +do { \ + if (color->elt[0] == 0 && color->elt[1] == 0 && \ + color->elt[2] == 0 && color->elt[3] == 0) \ + return S_008F3C_BORDER_COLOR_TYPE(V_008F3C_SQ_TEX_BORDER_COLOR_TRANS_BLACK); \ + if (color->elt[0] == 0 && color->elt[1] == 0 && \ + color->elt[2] == 0 && color->elt[3] == 1) \ + return S_008F3C_BORDER_COLOR_TYPE(V_008F3C_SQ_TEX_BORDER_COLOR_OPAQUE_BLACK); \ + if (color->elt[0] == 1 && color->elt[1] == 1 && \ + color->elt[2] == 1 && color->elt[3] == 1) \ + return S_008F3C_BORDER_COLOR_TYPE(V_008F3C_SQ_TEX_BORDER_COLOR_OPAQUE_WHITE); \ +} while (false) + + if (is_integer) + simple_border_types(ui); + else + simple_border_types(f); + +#undef simple_border_types int i; @@ -3984,7 +4002,11 @@ static void *si_create_sampler_state(struct pipe_context *ctx, 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] = si_translate_border_color(sctx, state, &state->border_color); + rstate->val[3] = si_translate_border_color(sctx, state, &state->border_color, false); + + /* Create sampler resource for integer textures. */ + memcpy(rstate->integer_val, rstate->val, sizeof(rstate->val)); + rstate->integer_val[3] = si_translate_border_color(sctx, state, &state->border_color, true); /* Create sampler resource for upgraded depth textures. */ memcpy(rstate->upgraded_depth_val, rstate->val, sizeof(rstate->val)); @@ -3999,7 +4021,7 @@ static void *si_create_sampler_state(struct pipe_context *ctx, 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) | + si_translate_border_color(sctx, state, &clamped_border_color, false) | S_008F3C_UPGRADED_DEPTH(1); return rstate; |