From: Marek Olšák <marek.ol...@amd.com> --- src/gallium/drivers/radeonsi/si_shader.h | 1 + src/gallium/drivers/radeonsi/si_state_shaders.c | 40 +++++++++++++++---------- 2 files changed, 25 insertions(+), 16 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index aab902b..7112621 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -329,20 +329,21 @@ struct si_shader_selector { /* GS parameters. */ unsigned esgs_itemsize; unsigned gs_input_verts_per_prim; unsigned gs_output_prim; unsigned gs_max_out_vertices; unsigned gs_num_invocations; unsigned max_gs_stream; /* count - 1 */ unsigned gsvs_vertex_size; unsigned max_gsvs_emit_size; + unsigned enabled_streamout_buffer_mask; /* PS parameters. */ unsigned color_attr_index[2]; unsigned db_shader_control; /* Set 0xf or 0x0 (4 bits) per each written output. * ANDed with spi_shader_col_format. */ unsigned colors_written_4bit; /* CS parameters */ diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index 55e881c..5cbb91b 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -1949,20 +1949,27 @@ static void *si_create_shader_selector(struct pipe_context *ctx, } sel->so = state->stream_output; tgsi_scan_shader(state->tokens, &sel->info); sel->type = sel->info.processor; p_atomic_inc(&sscreen->b.num_shaders_created); si_get_active_slot_masks(&sel->info, &sel->active_const_and_shader_buffers, &sel->active_samplers_and_images); + /* Record which streamout buffers are enabled. */ + for (i = 0; i < sel->so.num_outputs; i++) { + sel->enabled_streamout_buffer_mask |= + (1 << sel->so.output[i].output_buffer) << + (sel->so.output[i].stream * 4); + } + /* The prolog is a no-op if there are no inputs. */ sel->vs_needs_prolog = sel->type == PIPE_SHADER_VERTEX && sel->info.num_inputs; /* Set which opcode uses which (i,j) pair. */ if (sel->info.uses_persp_opcode_interp_centroid) sel->info.uses_persp_centroid = true; if (sel->info.uses_linear_opcode_interp_centroid) sel->info.uses_linear_centroid = true; @@ -2130,34 +2137,49 @@ static void *si_create_shader_selector(struct pipe_context *ctx, r600_can_dump_shader(&sscreen->b, sel->info.processor)) si_init_shader_selector_async(sel, -1); else util_queue_add_job(&sscreen->shader_compiler_queue, sel, &sel->ready, si_init_shader_selector_async, NULL); return sel; } +static void si_update_streamout_state(struct si_context *sctx) +{ + struct si_shader_selector *shader_with_so = + sctx->gs_shader.cso ? sctx->gs_shader.cso : + sctx->tes_shader.cso ? sctx->tes_shader.cso : + sctx->vs_shader.cso; + if (!shader_with_so) + return; + + sctx->b.streamout.enabled_stream_buffers_mask = + shader_with_so->enabled_streamout_buffer_mask; + sctx->b.streamout.stride_in_dw = shader_with_so->so.stride; +} + static void si_bind_vs_shader(struct pipe_context *ctx, void *state) { struct si_context *sctx = (struct si_context *)ctx; struct si_shader_selector *sel = state; if (sctx->vs_shader.cso == sel) return; sctx->vs_shader.cso = sel; sctx->vs_shader.current = sel ? sel->first_variant : NULL; sctx->do_update_shaders = true; si_mark_atom_dirty(sctx, &sctx->clip_regs); r600_update_vs_writes_viewport_index(&sctx->b, si_get_vs_info(sctx)); si_set_active_descriptors_for_shader(sctx, sel); + si_update_streamout_state(sctx); } static void si_update_tess_uses_prim_id(struct si_context *sctx) { sctx->ia_multi_vgt_param_key.u.tess_uses_prim_id = (sctx->tes_shader.cso && sctx->tes_shader.cso->info.uses_primid) || (sctx->tcs_shader.cso && sctx->tcs_shader.cso->info.uses_primid) || (sctx->gs_shader.cso && @@ -2182,20 +2204,21 @@ static void si_bind_gs_shader(struct pipe_context *ctx, void *state) si_mark_atom_dirty(sctx, &sctx->clip_regs); sctx->last_rast_prim = -1; /* reset this so that it gets updated */ if (enable_changed) { si_shader_change_notify(sctx); if (sctx->ia_multi_vgt_param_key.u.uses_tess) si_update_tess_uses_prim_id(sctx); } r600_update_vs_writes_viewport_index(&sctx->b, si_get_vs_info(sctx)); si_set_active_descriptors_for_shader(sctx, sel); + si_update_streamout_state(sctx); } static void si_bind_tcs_shader(struct pipe_context *ctx, void *state) { struct si_context *sctx = (struct si_context *)ctx; struct si_shader_selector *sel = state; bool enable_changed = !!sctx->tcs_shader.cso != !!sel; if (sctx->tcs_shader.cso == sel) return; @@ -2227,20 +2250,21 @@ static void si_bind_tes_shader(struct pipe_context *ctx, void *state) sctx->do_update_shaders = true; si_mark_atom_dirty(sctx, &sctx->clip_regs); sctx->last_rast_prim = -1; /* reset this so that it gets updated */ if (enable_changed) { si_shader_change_notify(sctx); sctx->last_tes_sh_base = -1; /* invalidate derived tess state */ } r600_update_vs_writes_viewport_index(&sctx->b, si_get_vs_info(sctx)); si_set_active_descriptors_for_shader(sctx, sel); + si_update_streamout_state(sctx); } static void si_bind_ps_shader(struct pipe_context *ctx, void *state) { struct si_context *sctx = (struct si_context *)ctx; struct si_shader_selector *sel = state; /* skip if supplied shader is one already in use */ if (sctx->ps_shader.cso == sel) return; @@ -2984,32 +3008,20 @@ static void si_update_vgt_shader_config(struct si_context *sctx) } if (sctx->b.chip_class >= GFX9) stages |= S_028B54_MAX_PRIMGRP_IN_WAVE(2); si_pm4_set_reg(*pm4, R_028B54_VGT_SHADER_STAGES_EN, stages); } si_pm4_bind_state(sctx, vgt_shader_config, *pm4); } -static void si_update_so(struct si_context *sctx, struct si_shader_selector *shader) -{ - struct pipe_stream_output_info *so = &shader->so; - uint32_t enabled_stream_buffers_mask = 0; - int i; - - for (i = 0; i < so->num_outputs; i++) - enabled_stream_buffers_mask |= (1 << so->output[i].output_buffer) << (so->output[i].stream * 4); - sctx->b.streamout.enabled_stream_buffers_mask = enabled_stream_buffers_mask; - sctx->b.streamout.stride_in_dw = shader->so.stride; -} - bool si_update_shaders(struct si_context *sctx) { struct pipe_context *ctx = (struct pipe_context*)sctx; struct si_compiler_ctx_state compiler_state; struct si_state_rasterizer *rs = sctx->queued.named.rasterizer; struct si_shader *old_vs = si_get_vs_state(sctx); bool old_clip_disable = old_vs ? old_vs->key.opt.hw_vs.clip_disable : false; int r; compiler_state.tm = sctx->tm; @@ -3063,54 +3075,50 @@ bool si_update_shaders(struct si_context *sctx) return false; si_pm4_bind_state(sctx, es, sctx->tes_shader.current->pm4); } } else { /* TES as VS */ r = si_shader_select(ctx, &sctx->tes_shader, &compiler_state); if (r) return false; si_pm4_bind_state(sctx, vs, sctx->tes_shader.current->pm4); - si_update_so(sctx, sctx->tes_shader.cso); } } else if (sctx->gs_shader.cso) { if (sctx->b.chip_class <= VI) { /* VS as ES */ r = si_shader_select(ctx, &sctx->vs_shader, &compiler_state); if (r) return false; si_pm4_bind_state(sctx, es, sctx->vs_shader.current->pm4); si_pm4_bind_state(sctx, ls, NULL); si_pm4_bind_state(sctx, hs, NULL); } } else { /* VS as VS */ r = si_shader_select(ctx, &sctx->vs_shader, &compiler_state); if (r) return false; si_pm4_bind_state(sctx, vs, sctx->vs_shader.current->pm4); - si_update_so(sctx, sctx->vs_shader.cso); - si_pm4_bind_state(sctx, ls, NULL); si_pm4_bind_state(sctx, hs, NULL); } /* Update GS. */ if (sctx->gs_shader.cso) { r = si_shader_select(ctx, &sctx->gs_shader, &compiler_state); if (r) return false; si_pm4_bind_state(sctx, gs, sctx->gs_shader.current->pm4); si_pm4_bind_state(sctx, vs, sctx->gs_shader.cso->gs_copy_shader->pm4); - si_update_so(sctx, sctx->gs_shader.cso); if (!si_update_gs_ring_buffers(sctx)) return false; } else { si_pm4_bind_state(sctx, gs, NULL); if (sctx->b.chip_class <= VI) si_pm4_bind_state(sctx, es, NULL); } si_update_vgt_shader_config(sctx); -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev