radeonsi: move sampler descriptors from IB to memory
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 <michel.daenzer@amd.com>
This commit is contained in:
@@ -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 &
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,77 +2794,25 @@ 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);
|
||||
struct si_context *sctx = (struct si_context *)ctx;
|
||||
|
||||
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:
|
||||
;
|
||||
}
|
||||
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)
|
||||
{
|
||||
struct si_context *sctx = (struct si_context *)ctx;
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user