From dd46841bc9685b48c972ebe5f5cf92770cf025fd Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Wed, 18 Jun 2014 02:46:49 +0200 Subject: [PATCH] radeonsi: move sampler descriptors from IB to memory MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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. Reviewed-by: Michel Dänzer --- 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 | 91 ++++--------------- src/gallium/drivers/radeonsi/si_state.h | 12 ++- 5 files changed, 82 insertions(+), 82 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c index 072024aa323..a76d9052494 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 4dd831a7aad..01fcec3e13d 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -363,6 +363,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) @@ -985,9 +1031,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; } @@ -1006,6 +1057,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); } } @@ -1017,5 +1069,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 c95774d6f5e..901beb279a0 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -63,11 +63,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 { @@ -102,6 +101,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 c106747a67d..44c1af844fc 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -2738,22 +2738,18 @@ 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 the buffer gets reallocated. + */ +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]) == @@ -2786,14 +2782,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); @@ -2801,76 +2794,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); - si_set_sampler_states(sctx, pm4, count, states, - &sctx->samplers[PIPE_SHADER_VERTEX], - R_00B330_SPI_SHADER_USER_DATA_ES_0); - 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 ae42e6673b5..7a0433c1b9d 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, -- 2.30.2