From 91cf6c1e92eab5e263f46ac38edc07d7bdbd10b3 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 21 Jun 2013 14:22:09 +0800 Subject: [PATCH] ilo: map SO registers at shader compile time The unmodified pipe_stream_output_info describes its outputs as if they are in TGSI_FILE_OUTPUT. Remap the register indices to where they appear in the VUE. TGSI_SEMANTIC_PSIZE needs a little care because it is at the W channel. --- .../drivers/ilo/ilo_3d_pipeline_gen7.c | 16 +++--- src/gallium/drivers/ilo/ilo_gpe_gen7.c | 36 +++---------- src/gallium/drivers/ilo/ilo_gpe_gen7.h | 1 - src/gallium/drivers/ilo/ilo_shader.c | 51 +++++++++++++++++++ src/gallium/drivers/ilo/ilo_shader.h | 3 ++ .../drivers/ilo/shader/ilo_shader_internal.h | 2 + 6 files changed, 72 insertions(+), 37 deletions(-) diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c index 8ea93313701..49f5049cb2e 100644 --- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c +++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c @@ -378,20 +378,20 @@ gen7_pipeline_sol(struct ilo_3d_pipeline *p, struct gen6_pipeline_session *session) { const struct pipe_stream_output_info *so_info; - const struct ilo_shader *sh; + const struct ilo_shader_state *shader; bool dirty_sh = false; if (ilo->gs) { - so_info = &ilo->gs->info.stream_output; - sh = ilo->gs->shader; + shader = ilo->gs; dirty_sh = DIRTY(GS); } else { - so_info = &ilo->vs->info.stream_output; - sh = ilo->vs->shader; + shader = ilo->vs; dirty_sh = DIRTY(VS); } + so_info = ilo_shader_get_kernel_so_info(shader); + gen6_pipeline_update_max_svbi(p, ilo, session); /* 3DSTATE_SO_BUFFER */ @@ -419,13 +419,15 @@ gen7_pipeline_sol(struct ilo_3d_pipeline *p, /* 3DSTATE_SO_DECL_LIST */ if (dirty_sh && ilo->so.enabled) - p->gen7_3DSTATE_SO_DECL_LIST(p->dev, so_info, sh, p->cp); + p->gen7_3DSTATE_SO_DECL_LIST(p->dev, so_info, p->cp); /* 3DSTATE_STREAMOUT */ if (DIRTY(STREAM_OUTPUT_TARGETS) || DIRTY(RASTERIZER) || dirty_sh) { const unsigned buffer_mask = (1 << ilo->so.count) - 1; + const int output_count = ilo_shader_get_kernel_param(shader, + ILO_KERNEL_OUTPUT_COUNT); - p->gen7_3DSTATE_STREAMOUT(p->dev, buffer_mask, sh->out.count, + p->gen7_3DSTATE_STREAMOUT(p->dev, buffer_mask, output_count, ilo->rasterizer->state.rasterizer_discard, p->cp); } } diff --git a/src/gallium/drivers/ilo/ilo_gpe_gen7.c b/src/gallium/drivers/ilo/ilo_gpe_gen7.c index 3ad109c91a9..41eb0b31cc6 100644 --- a/src/gallium/drivers/ilo/ilo_gpe_gen7.c +++ b/src/gallium/drivers/ilo/ilo_gpe_gen7.c @@ -1102,7 +1102,6 @@ gen7_emit_3DSTATE_PUSH_CONSTANT_ALLOC_PS(const struct ilo_dev_info *dev, static void gen7_emit_3DSTATE_SO_DECL_LIST(const struct ilo_dev_info *dev, const struct pipe_stream_output_info *so_info, - const struct ilo_shader *sh, struct ilo_cp *cp) { const uint32_t cmd = ILO_GPE_CMD(0x3, 0x1, 0x17); @@ -1121,7 +1120,7 @@ gen7_emit_3DSTATE_SO_DECL_LIST(const struct ilo_dev_info *dev, memset(buffer_offsets, 0, sizeof(buffer_offsets)); for (i = 0; i < so_info->num_outputs; i++) { - unsigned decl, buf, attr, mask; + unsigned decl, buf, reg, mask; buf = so_info->output[i].output_buffer; @@ -1142,34 +1141,13 @@ gen7_emit_3DSTATE_SO_DECL_LIST(const struct ilo_dev_info *dev, buffer_offsets[buf] += num_dwords; } - /* figure out which attribute is sourced */ - for (attr = 0; attr < sh->out.count; attr++) { - const int idx = sh->out.register_indices[attr]; - if (idx == so_info->output[i].register_index) - break; - } - - decl = buf << SO_DECL_OUTPUT_BUFFER_SLOT_SHIFT; - - if (attr < sh->out.count) { - mask = ((1 << so_info->output[i].num_components) - 1) << - so_info->output[i].start_component; + reg = so_info->output[i].register_index; + mask = ((1 << so_info->output[i].num_components) - 1) << + so_info->output[i].start_component; - /* PSIZE is at W channel */ - if (sh->out.semantic_names[attr] == TGSI_SEMANTIC_PSIZE) { - assert(mask == 0x1); - mask = (mask << 3) & 0xf; - } - - decl |= attr << SO_DECL_REGISTER_INDEX_SHIFT | - mask << SO_DECL_COMPONENT_MASK_SHIFT; - } - else { - assert(!"stream output an undefined register"); - mask = (1 << so_info->output[i].num_components) - 1; - decl |= SO_DECL_HOLE_FLAG | - mask << SO_DECL_COMPONENT_MASK_SHIFT; - } + decl = buf << SO_DECL_OUTPUT_BUFFER_SLOT_SHIFT | + reg << SO_DECL_REGISTER_INDEX_SHIFT | + mask << SO_DECL_COMPONENT_MASK_SHIFT; so_decls[num_entries++] = decl; buffer_selects |= 1 << buf; diff --git a/src/gallium/drivers/ilo/ilo_gpe_gen7.h b/src/gallium/drivers/ilo/ilo_gpe_gen7.h index f6b0540486f..da172dfcb4b 100644 --- a/src/gallium/drivers/ilo/ilo_gpe_gen7.h +++ b/src/gallium/drivers/ilo/ilo_gpe_gen7.h @@ -360,7 +360,6 @@ typedef void typedef void (*ilo_gpe_gen7_3DSTATE_SO_DECL_LIST)(const struct ilo_dev_info *dev, const struct pipe_stream_output_info *so_info, - const struct ilo_shader *sh, struct ilo_cp *cp); typedef void diff --git a/src/gallium/drivers/ilo/ilo_shader.c b/src/gallium/drivers/ilo/ilo_shader.c index c2d5623fc26..2cff95bd994 100644 --- a/src/gallium/drivers/ilo/ilo_shader.c +++ b/src/gallium/drivers/ilo/ilo_shader.c @@ -610,6 +610,42 @@ ilo_shader_state_search_variant(struct ilo_shader_state *state, return sh; } +static void +copy_so_info(struct ilo_shader *sh, + const struct pipe_stream_output_info *so_info) +{ + unsigned i, attr; + + if (!so_info->num_outputs) + return; + + sh->so_info = *so_info; + + for (i = 0; i < so_info->num_outputs; i++) { + /* figure out which attribute is sourced */ + for (attr = 0; attr < sh->out.count; attr++) { + const int reg_idx = sh->out.register_indices[attr]; + if (reg_idx == so_info->output[i].register_index) + break; + } + + if (attr < sh->out.count) { + sh->so_info.output[i].register_index = attr; + } + else { + assert(!"stream output an undefined register"); + sh->so_info.output[i].register_index = 0; + } + + /* PSIZE is at W channel */ + if (sh->out.semantic_names[attr] == TGSI_SEMANTIC_PSIZE) { + assert(so_info->output[i].start_component == 0); + assert(so_info->output[i].num_components == 1); + sh->so_info.output[i].start_component = 3; + } + } +} + /** * Add a shader variant to the shader state. */ @@ -643,6 +679,8 @@ ilo_shader_state_add_variant(struct ilo_shader_state *state, sh->variant = *variant; + copy_so_info(sh, &state->info.stream_output); + ilo_shader_state_add_shader(state, sh); return sh; @@ -927,3 +965,16 @@ ilo_shader_get_kernel_cso(const struct ilo_shader_state *shader) return &kernel->cso; } + +/** + * Return the SO info of the selected kernel. + */ +const struct pipe_stream_output_info * +ilo_shader_get_kernel_so_info(const struct ilo_shader_state *shader) +{ + const struct ilo_shader *kernel = shader->shader; + + assert(kernel); + + return &kernel->so_info; +} diff --git a/src/gallium/drivers/ilo/ilo_shader.h b/src/gallium/drivers/ilo/ilo_shader.h index 92ad7f6656f..d326b9c01f4 100644 --- a/src/gallium/drivers/ilo/ilo_shader.h +++ b/src/gallium/drivers/ilo/ilo_shader.h @@ -124,4 +124,7 @@ ilo_shader_get_kernel_param(const struct ilo_shader_state *shader, const struct ilo_shader_cso * ilo_shader_get_kernel_cso(const struct ilo_shader_state *shader); +const struct pipe_stream_output_info * +ilo_shader_get_kernel_so_info(const struct ilo_shader_state *shader); + #endif /* ILO_SHADER_H */ diff --git a/src/gallium/drivers/ilo/shader/ilo_shader_internal.h b/src/gallium/drivers/ilo/shader/ilo_shader_internal.h index c999d8abdb5..3515e3f1d9f 100644 --- a/src/gallium/drivers/ilo/shader/ilo_shader_internal.h +++ b/src/gallium/drivers/ilo/shader/ilo_shader_internal.h @@ -105,6 +105,8 @@ struct ilo_shader { bool stream_output; int svbi_post_inc; + struct pipe_stream_output_info so_info; + /* for VS stream output / rasterizer discard */ int gs_offsets[3]; int gs_start_grf; -- 2.30.2