ilo: map SO registers at shader compile time
authorChia-I Wu <olvaffe@gmail.com>
Fri, 21 Jun 2013 06:22:09 +0000 (14:22 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Tue, 25 Jun 2013 05:18:08 +0000 (13:18 +0800)
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.

src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c
src/gallium/drivers/ilo/ilo_gpe_gen7.c
src/gallium/drivers/ilo/ilo_gpe_gen7.h
src/gallium/drivers/ilo/ilo_shader.c
src/gallium/drivers/ilo/ilo_shader.h
src/gallium/drivers/ilo/shader/ilo_shader_internal.h

index 8ea93313701aae356478ec37686062cd70320100..49f5049cb2e41e3f9ef60c77964a142ac0af5466 100644 (file)
@@ -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);
    }
 }
index 3ad109c91a9d3efda4ae0b062a2b65c7ed2cd431..41eb0b31cc65de61ac6e52adb686e4a674409f32 100644 (file)
@@ -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;
index f6b0540486f22f2bac2b9aaff0d10aceec379003..da172dfcb4b03032b3ab7506e7517402bbb8ae93 100644 (file)
@@ -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
index c2d5623fc2622c40456c6c587ee8928f1ab9265a..2cff95bd994870bba7e80a7d92f6872afee0cef9 100644 (file)
@@ -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;
+}
index 92ad7f6656f7ecf0da3ee6e1bc6e3115712d9b4e..d326b9c01f471ae59b6a43db621a035481737dab 100644 (file)
@@ -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 */
index c999d8abdb5da6a93d40050366f93d0627a04929..3515e3f1d9fb23417cf65d181eed17baafa33a1a 100644 (file)
@@ -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;