For the series: Reviewed-by: Marek Olšák <marek.ol...@amd.com>
Marek On Tue, Sep 26, 2017 at 4:46 PM, Nicolai Hähnle <nhaeh...@gmail.com> wrote: > From: Nicolai Hähnle <nicolai.haeh...@amd.com> > > This fixes the extremely unlikely case that an application uses > 0x80000000 or 0x3f800000 as border color for an integer texture and > helps in the also, but perhaps slightly less, unlikely case that 1 is > used as a border color. > --- > src/gallium/drivers/radeonsi/si_descriptors.c | 37 ++++++++++++-------- > src/gallium/drivers/radeonsi/si_pipe.h | 2 ++ > 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 27239c25389..db77b1cb982 100644 > --- a/src/gallium/drivers/radeonsi/si_descriptors.c > +++ b/src/gallium/drivers/radeonsi/si_descriptors.c > @@ -372,20 +372,34 @@ void si_set_mutable_tex_desc_fields(struct si_screen > *sscreen, > unsigned pitch = base_level_info->nblk_x * block_width; > unsigned index = si_tile_mode_index(tex, base_level, > is_stencil); > > state[3] &= C_008F1C_TILING_INDEX; > state[3] |= S_008F1C_TILING_INDEX(index); > state[4] &= C_008F20_PITCH_GFX6; > state[4] |= S_008F20_PITCH_GFX6(pitch - 1); > } > } > > +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, > uint32_t *desc) > { > struct pipe_sampler_view *view = &sview->base; > struct r600_texture *rtex = (struct r600_texture *)view->texture; > bool is_buffer = rtex->resource.b.b.target == PIPE_BUFFER; > > if (unlikely(!is_buffer && sview->dcc_incompatible)) { > @@ -415,27 +429,24 @@ static void si_set_sampler_view_desc(struct si_context > *sctx, > is_separate_stencil, > desc); > } > > if (!is_buffer && rtex->fmask.size) { > memcpy(desc + 8, sview->fmask_state, 8*4); > } else { > /* 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); > } > } > > static void si_set_sampler_view(struct si_context *sctx, > unsigned shader, > unsigned slot, struct pipe_sampler_view *view, > bool disallow_early_out) > { > struct si_sampler_views *views = &sctx->samplers[shader].views; > struct si_sampler_view *rview = (struct si_sampler_view*)view; > @@ -463,22 +474,22 @@ static void si_set_sampler_view(struct si_context *sctx, > si_sampler_view_add_buffer(sctx, view->texture, > RADEON_USAGE_READ, > rview->is_stencil_sampler, true); > } else { > pipe_sampler_view_reference(&views->views[slot], NULL); > memcpy(desc, null_texture_descriptor, 8*4); > /* Only clear the lower dwords of FMASK. */ > 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); > } > > sctx->descriptors_dirty |= 1u << > si_sampler_and_image_descriptors_idx(shader); > } > > static bool color_needs_decompression(struct r600_texture *rtex) > { > return rtex->fmask.size || > @@ -855,26 +866,22 @@ static void si_bind_sampler_states(struct pipe_context > *ctx, > > struct r600_texture *tex = NULL; > > if (sview && sview->base.texture && > sview->base.texture->target != PIPE_BUFFER) > tex = (struct r600_texture *)sview->base.texture; > > 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); > } > } > > /* BUFFER RESOURCES */ > > static void si_init_buffer_resources(struct si_buffer_resources *buffers, > struct si_descriptors *descs, > unsigned num_buffers, > 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 > @@ -150,30 +150,32 @@ struct si_blend_color { > struct si_sampler_view { > struct pipe_sampler_view base; > /* [0..7] = image descriptor > * [4..7] = buffer descriptor */ > uint32_t state[8]; > uint32_t fmask_state[8]; > const struct legacy_surf_level *base_level_info; > ubyte base_level; > ubyte block_width; > bool is_stencil_sampler; > + bool is_integer; > bool dcc_incompatible; > }; > > #define SI_SAMPLER_STATE_MAGIC 0x34f1c35a > > struct si_sampler_state { > #ifdef DEBUG > unsigned magic; > #endif > uint32_t val[4]; > + uint32_t integer_val[4]; > uint32_t upgraded_depth_val[4]; > }; > > struct si_cs_shader_state { > struct si_compute *program; > struct si_compute *emitted_program; > unsigned offset; > bool initialized; > bool uses_scratch; > }; > diff --git a/src/gallium/drivers/radeonsi/si_state.c > b/src/gallium/drivers/radeonsi/si_state.c > index 2a27ea0c503..75042b6dfd3 100644 > --- a/src/gallium/drivers/radeonsi/si_state.c > +++ b/src/gallium/drivers/radeonsi/si_state.c > @@ -3854,20 +3854,26 @@ si_create_sampler_view_custom(struct pipe_context > *ctx, > state->u.tex.first_level, > state->format); > > si_make_texture_descriptor(sctx->screen, tmp, true, > state->target, pipe_format, state_swizzle, > first_level, last_level, > state->u.tex.first_layer, last_layer, > 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); > return &view->base; > } > > static struct pipe_sampler_view * > si_create_sampler_view(struct pipe_context *ctx, > struct pipe_resource *texture, > const struct pipe_sampler_view *state) > @@ -3890,38 +3896,50 @@ 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 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; > > /* 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) { > @@ -3977,36 +3995,40 @@ 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] = 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)); > > 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) | > + si_translate_border_color(sctx, state, > &clamped_border_color, false) | > 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) > -- > 2.11.0 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev