From: Marek Olšák <marek.ol...@amd.com>

Sampler descriptors are now represented by si_descriptors.
This also adds support for fine-grained sampler state updates and
the border color update is now isolated in a separate function.

Border colors have been broken if texturing from multiple shader stages is
used. This patch doesn't change that.

BTW, blitting already makes use of fine-grained state updates.
u_blitter uses 2 textures at most, so we only have to save 2.
---
 src/gallium/drivers/radeonsi/si_blit.c        |  4 +-
 src/gallium/drivers/radeonsi/si_descriptors.c | 53 +++++++++++++++
 src/gallium/drivers/radeonsi/si_pipe.h        |  4 +-
 src/gallium/drivers/radeonsi/si_state.c       | 96 ++++++---------------------
 src/gallium/drivers/radeonsi/si_state.h       | 12 +++-
 5 files changed, 85 insertions(+), 84 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_blit.c 
b/src/gallium/drivers/radeonsi/si_blit.c
index 072024a..a76d905 100644
--- a/src/gallium/drivers/radeonsi/si_blit.c
+++ b/src/gallium/drivers/radeonsi/si_blit.c
@@ -71,8 +71,8 @@ static void si_blitter_begin(struct pipe_context *ctx, enum 
si_blitter_op op)
 
        if (op & SI_SAVE_TEXTURES) {
                util_blitter_save_fragment_sampler_states(
-                       sctx->blitter, 
sctx->samplers[PIPE_SHADER_FRAGMENT].n_samplers,
-                       (void**)sctx->samplers[PIPE_SHADER_FRAGMENT].samplers);
+                       sctx->blitter, 2,
+                       
sctx->samplers[PIPE_SHADER_FRAGMENT].states.saved_states);
 
                util_blitter_save_fragment_sampler_views(sctx->blitter,
                        
util_last_bit(sctx->samplers[PIPE_SHADER_FRAGMENT].views.desc.enabled_mask &
diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c 
b/src/gallium/drivers/radeonsi/si_descriptors.c
index 6ae9b82..2edfe2e 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -365,6 +365,52 @@ void si_set_sampler_view(struct si_context *sctx, unsigned 
shader,
        si_update_descriptors(sctx, &views->desc);
 }
 
+/* SAMPLER STATES */
+
+static void si_emit_sampler_states(struct si_context *sctx, struct r600_atom 
*atom)
+{
+       struct si_sampler_states *states = (struct si_sampler_states*)atom;
+
+       si_emit_descriptors(sctx, &states->desc, states->desc_data);
+}
+
+static void si_sampler_states_begin_new_cs(struct si_context *sctx,
+                                          struct si_sampler_states *states)
+{
+       r600_context_bo_reloc(&sctx->b, &sctx->b.rings.gfx, states->desc.buffer,
+                             RADEON_USAGE_READWRITE, RADEON_PRIO_SHADER_DATA);
+       si_emit_shader_pointer(sctx, &states->desc);
+}
+
+void si_set_sampler_descriptors(struct si_context *sctx, unsigned shader,
+                               unsigned start, unsigned count, void **states)
+{
+       struct si_sampler_states *samplers = &sctx->samplers[shader].states;
+       struct si_pipe_sampler_state **sstates = (struct 
si_pipe_sampler_state**)states;
+       int i;
+
+       if (start == 0)
+               samplers->saved_states[0] = states[0];
+       if (start == 1)
+               samplers->saved_states[1] = states[0];
+       else if (start == 0 && count >= 2)
+               samplers->saved_states[1] = states[1];
+
+       for (i = 0; i < count; i++) {
+               unsigned slot = start + i;
+
+               if (!sstates[i]) {
+                       samplers->desc.dirty_mask &= ~(1 << slot);
+                       continue;
+               }
+
+               samplers->desc_data[slot] = sstates[i]->val;
+               samplers->desc.dirty_mask |= 1 << slot;
+       }
+
+       si_update_descriptors(sctx, &samplers->desc);
+}
+
 /* BUFFER RESOURCES */
 
 static void si_emit_buffer_resources(struct si_context *sctx, struct r600_atom 
*atom)
@@ -987,9 +1033,14 @@ void si_init_all_descriptors(struct si_context *sctx)
 
                si_init_sampler_views(sctx, &sctx->samplers[i].views, i);
 
+               si_init_descriptors(sctx, &sctx->samplers[i].states.desc,
+                                   si_get_shader_user_data_base(i) + 
SI_SGPR_SAMPLER * 4,
+                                   4, SI_NUM_SAMPLER_STATES, 
si_emit_sampler_states);
+
                sctx->atoms.s.const_buffers[i] = 
&sctx->const_buffers[i].desc.atom;
                sctx->atoms.s.rw_buffers[i] = &sctx->rw_buffers[i].desc.atom;
                sctx->atoms.s.sampler_views[i] = 
&sctx->samplers[i].views.desc.atom;
+               sctx->atoms.s.sampler_states[i] = 
&sctx->samplers[i].states.desc.atom;
        }
 
 
@@ -1008,6 +1059,7 @@ void si_release_all_descriptors(struct si_context *sctx)
                si_release_buffer_resources(&sctx->const_buffers[i]);
                si_release_buffer_resources(&sctx->rw_buffers[i]);
                si_release_sampler_views(&sctx->samplers[i].views);
+               si_release_descriptors(&sctx->samplers[i].states.desc);
        }
 }
 
@@ -1019,5 +1071,6 @@ void si_all_descriptors_begin_new_cs(struct si_context 
*sctx)
                si_buffer_resources_begin_new_cs(sctx, &sctx->const_buffers[i]);
                si_buffer_resources_begin_new_cs(sctx, &sctx->rw_buffers[i]);
                si_sampler_views_begin_new_cs(sctx, &sctx->samplers[i].views);
+               si_sampler_states_begin_new_cs(sctx, &sctx->samplers[i].states);
        }
 }
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h 
b/src/gallium/drivers/radeonsi/si_pipe.h
index 9a6410b..46ea7dd 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -67,11 +67,10 @@ struct si_cs_shader_state {
 
 struct si_textures_info {
        struct si_sampler_views         views;
-       struct si_pipe_sampler_state    *samplers[SI_NUM_USER_SAMPLERS];
+       struct si_sampler_states        states;
        unsigned                        n_views;
        uint32_t                        depth_texture_mask; /* which textures 
are depth */
        uint32_t                        compressed_colortex_mask;
-       unsigned                        n_samplers;
 };
 
 struct si_framebuffer {
@@ -106,6 +105,7 @@ struct si_context {
                        struct r600_atom *const_buffers[SI_NUM_SHADERS];
                        struct r600_atom *rw_buffers[SI_NUM_SHADERS];
                        struct r600_atom *sampler_views[SI_NUM_SHADERS];
+                       struct r600_atom *sampler_states[SI_NUM_SHADERS];
                        /* Caches must be flushed after resource descriptors are
                         * updated in memory. */
                        struct r600_atom *cache_flush;
diff --git a/src/gallium/drivers/radeonsi/si_state.c 
b/src/gallium/drivers/radeonsi/si_state.c
index c64958a..eb63d3e 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -2753,22 +2753,21 @@ static void si_set_sampler_views(struct pipe_context 
*ctx,
        sctx->b.flags |= R600_CONTEXT_INV_TEX_CACHE;
 }
 
-static void si_set_sampler_states(struct si_context *sctx,
-                                 struct si_pm4_state *pm4,
-                                 unsigned count, void **states,
-                                 struct si_textures_info *samplers,
-                                 unsigned user_data_reg)
+/* Upload border colors and update the pointers in resource descriptors.
+ * There can only be 4096 border colors per context.
+ *
+ * XXX: This is broken if sampler states are bound to multiple shader stages,
+ *      because TA_BC_BASE_ADDR is shared by all of them and we overwrite it
+ *      for stages which were set earlier. This is also broken for
+ *      fine-grained sampler state updates.
+ */
+static void si_set_border_colors(struct si_context *sctx, unsigned count,
+                                void **states)
 {
        struct si_pipe_sampler_state **rstates = (struct si_pipe_sampler_state 
**)states;
        uint32_t *border_color_table = NULL;
        int i, j;
 
-       if (!count)
-               goto out;
-
-       sctx->b.flags |= R600_CONTEXT_INV_TEX_CACHE;
-
-       si_pm4_sh_data_begin(pm4);
        for (i = 0; i < count; i++) {
                if (rstates[i] &&
                    G_008F3C_BORDER_COLOR_TYPE(rstates[i]->val[3]) ==
@@ -2801,14 +2800,11 @@ static void si_set_sampler_states(struct si_context 
*sctx,
                        rstates[i]->val[3] &= C_008F3C_BORDER_COLOR_PTR;
                        rstates[i]->val[3] |= 
S_008F3C_BORDER_COLOR_PTR(sctx->border_color_offset++);
                }
-
-               for (j = 0; j < Elements(rstates[i]->val); ++j) {
-                       si_pm4_sh_data_add(pm4, rstates[i] ? rstates[i]->val[j] 
: 0);
-               }
        }
-       si_pm4_sh_data_end(pm4, user_data_reg, SI_SGPR_SAMPLER);
 
        if (border_color_table) {
+               struct si_pm4_state *pm4 = si_pm4_alloc_state(sctx);
+
                uint64_t va_offset =
                        r600_resource_va(&sctx->screen->b.b,
                                         (void*)sctx->border_color_table);
@@ -2816,78 +2812,24 @@ static void si_set_sampler_states(struct si_context 
*sctx,
                si_pm4_set_reg(pm4, R_028080_TA_BC_BASE_ADDR, va_offset >> 8);
                if (sctx->b.chip_class >= CIK)
                        si_pm4_set_reg(pm4, R_028084_TA_BC_BASE_ADDR_HI, 
va_offset >> 40);
-               sctx->b.ws->buffer_unmap(sctx->border_color_table->cs_buf);
                si_pm4_add_bo(pm4, sctx->border_color_table, RADEON_USAGE_READ,
                              RADEON_PRIO_SHADER_DATA);
+               si_pm4_set_state(sctx, ta_bordercolor_base, pm4);
        }
-
-       memcpy(samplers->samplers, states, sizeof(void*) * count);
-
-out:
-       samplers->n_samplers = count;
-}
-
-static void si_bind_vs_sampler_states(struct pipe_context *ctx, unsigned 
count, void **states)
-{
-       struct si_context *sctx = (struct si_context *)ctx;
-       struct si_pm4_state *pm4 = si_pm4_alloc_state(sctx);
-
-       si_set_sampler_states(sctx, pm4, count, states,
-                             &sctx->samplers[PIPE_SHADER_VERTEX],
-                             R_00B130_SPI_SHADER_USER_DATA_VS_0);
-#if LLVM_SUPPORTS_GEOM_SHADERS
-       si_set_sampler_states(sctx, pm4, count, states,
-                             &sctx->samplers[PIPE_SHADER_VERTEX],
-                             R_00B330_SPI_SHADER_USER_DATA_ES_0);
-#endif
-       si_pm4_set_state(sctx, vs_sampler, pm4);
 }
 
-static void si_bind_gs_sampler_states(struct pipe_context *ctx, unsigned 
count, void **states)
-{
-       struct si_context *sctx = (struct si_context *)ctx;
-       struct si_pm4_state *pm4 = si_pm4_alloc_state(sctx);
-
-       si_set_sampler_states(sctx, pm4, count, states,
-                             &sctx->samplers[PIPE_SHADER_GEOMETRY],
-                             R_00B230_SPI_SHADER_USER_DATA_GS_0);
-       si_pm4_set_state(sctx, gs_sampler, pm4);
-}
-
-static void si_bind_ps_sampler_states(struct pipe_context *ctx, unsigned 
count, void **states)
-{
-       struct si_context *sctx = (struct si_context *)ctx;
-       struct si_pm4_state *pm4 = si_pm4_alloc_state(sctx);
-
-       si_set_sampler_states(sctx, pm4, count, states,
-                             &sctx->samplers[PIPE_SHADER_FRAGMENT],
-                             R_00B030_SPI_SHADER_USER_DATA_PS_0);
-       si_pm4_set_state(sctx, ps_sampler, pm4);
-}
-
-
 static void si_bind_sampler_states(struct pipe_context *ctx, unsigned shader,
                                    unsigned start, unsigned count,
                                    void **states)
 {
-   assert(start == 0);
-
-   switch (shader) {
-   case PIPE_SHADER_VERTEX:
-      si_bind_vs_sampler_states(ctx, count, states);
-      break;
-   case PIPE_SHADER_GEOMETRY:
-      si_bind_gs_sampler_states(ctx, count, states);
-      break;
-   case PIPE_SHADER_FRAGMENT:
-      si_bind_ps_sampler_states(ctx, count, states);
-      break;
-   default:
-      ;
-   }
-}
+       struct si_context *sctx = (struct si_context *)ctx;
 
+       if (!count || shader >= SI_NUM_SHADERS)
+               return;
 
+       si_set_border_colors(sctx, count, states);
+       si_set_sampler_descriptors(sctx, shader, start, count, states);
+}
 
 static void si_set_sample_mask(struct pipe_context *ctx, unsigned sample_mask)
 {
diff --git a/src/gallium/drivers/radeonsi/si_state.h 
b/src/gallium/drivers/radeonsi/si_state.h
index fc3b1b9..7820fcb 100644
--- a/src/gallium/drivers/radeonsi/si_state.h
+++ b/src/gallium/drivers/radeonsi/si_state.h
@@ -89,15 +89,13 @@ union si_state {
                struct si_pm4_state             *fb_rs;
                struct si_pm4_state             *fb_blend;
                struct si_pm4_state             *dsa_stencil_ref;
+               struct si_pm4_state             *ta_bordercolor_base;
                struct si_pm4_state             *es;
                struct si_pm4_state             *gs;
                struct si_pm4_state             *gs_rings;
-               struct si_pm4_state             *gs_sampler;
                struct si_pm4_state             *gs_onoff;
                struct si_pm4_state             *vs;
-               struct si_pm4_state             *vs_sampler;
                struct si_pm4_state             *ps;
-               struct si_pm4_state             *ps_sampler;
                struct si_pm4_state             *spi;
                struct si_pm4_state             *vertex_buffers;
                struct si_pm4_state             *draw_info;
@@ -174,6 +172,12 @@ struct si_sampler_views {
        uint32_t                        *desc_data[SI_NUM_SAMPLER_VIEWS];
 };
 
+struct si_sampler_states {
+       struct si_descriptors           desc;
+       uint32_t                        *desc_data[SI_NUM_SAMPLER_STATES];
+       void                            *saved_states[2]; /* saved for 
u_blitter */
+};
+
 struct si_buffer_resources {
        struct si_descriptors           desc;
        unsigned                        num_buffers;
@@ -218,6 +222,8 @@ struct si_buffer_resources {
 void si_set_sampler_view(struct si_context *sctx, unsigned shader,
                         unsigned slot, struct pipe_sampler_view *view,
                         unsigned *view_desc);
+void si_set_sampler_descriptors(struct si_context *sctx, unsigned shader,
+                               unsigned start, unsigned count, void **states);
 void si_set_ring_buffer(struct pipe_context *ctx, uint shader, uint slot,
                        struct pipe_constant_buffer *input,
                        unsigned stride, unsigned num_records,
-- 
1.9.1

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

Reply via email to