gallium: allow setting of the internal stream output offset
[mesa.git] / src / gallium / drivers / ilo / shader / ilo_shader_vs.c
index ff4e4be01cc04b22f13249596ccc53673cf40d32..c20ecc6f6a2d286793bbd1eacfd45bd46c34cfb8 100644 (file)
  */
 
 #include "tgsi/tgsi_dump.h"
+#include "tgsi/tgsi_util.h"
 #include "toy_compiler.h"
 #include "toy_tgsi.h"
 #include "toy_legalize.h"
 #include "toy_optimize.h"
 #include "toy_helpers.h"
 #include "ilo_context.h"
-#include "ilo_shader.h"
+#include "ilo_shader_internal.h"
 
 struct vs_compile_context {
    struct ilo_shader *shader;
@@ -46,6 +47,7 @@ struct vs_compile_context {
 
    int num_grf_per_vrf;
    int first_const_grf;
+   int first_ucp_grf;
    int first_vue_grf;
    int first_free_grf;
    int last_free_grf;
@@ -78,6 +80,27 @@ vs_lower_opcode_tgsi_in(struct vs_compile_context *vcc,
    }
 }
 
+static bool
+vs_lower_opcode_tgsi_const_pcb(struct vs_compile_context *vcc,
+                               struct toy_dst dst, int dim,
+                               struct toy_src idx)
+{
+   const int i = idx.val32;
+   const int grf = vcc->first_const_grf + i / 2;
+   const int grf_subreg = (i & 1) * 16;
+   struct toy_src src;
+
+   if (!vcc->variant->use_pcb || dim != 0 || idx.file != TOY_FILE_IMM ||
+       grf >= vcc->first_ucp_grf)
+      return false;
+
+
+   src = tsrc_rect(tsrc(TOY_FILE_GRF, grf, grf_subreg), TOY_RECT_041);
+   tc_MOV(&vcc->tc, dst, src);
+
+   return true;
+}
+
 static void
 vs_lower_opcode_tgsi_const_gen6(struct vs_compile_context *vcc,
                                 struct toy_dst dst, int dim,
@@ -93,6 +116,9 @@ vs_lower_opcode_tgsi_const_gen6(struct vs_compile_context *vcc,
    struct toy_inst *inst;
    struct toy_src desc;
 
+   if (vs_lower_opcode_tgsi_const_pcb(vcc, dst, dim, idx))
+      return;
+
    /* set message header */
    inst = tc_MOV(tc, header, r0);
    inst->mask_ctrl = BRW_MASK_DISABLE;
@@ -120,6 +146,9 @@ vs_lower_opcode_tgsi_const_gen7(struct vs_compile_context *vcc,
       tdst_ud(tdst(TOY_FILE_MRF, vcc->first_free_mrf, 0));
    struct toy_src desc;
 
+   if (vs_lower_opcode_tgsi_const_pcb(vcc, dst, dim, idx))
+      return;
+
    /*
     * In 259b65e2e7938de4aab323033cfe2b33369ddb07, pull constant load was
     * changed from OWord Dual Block Read to ld to increase performance in the
@@ -377,15 +406,24 @@ vs_prepare_tgsi_sampling(struct toy_compiler *tc, const struct toy_inst *inst,
    num_derivs = 0;
    sampler_src = 1;
 
-   num_coords = toy_tgsi_get_texture_coord_dim(inst->tex.target, &ref_pos);
+   num_coords = tgsi_util_get_texture_coord_dim(inst->tex.target, &ref_pos);
 
    /* extract the parameters */
    switch (inst->opcode) {
    case TOY_OPCODE_TGSI_TXD:
-      if (ref_pos >= 0)
-         tc_fail(tc, "TXD with shadow sampler not supported");
+      if (ref_pos >= 0) {
+         assert(ref_pos < 4);
+
+         msg_type = HSW_SAMPLER_MESSAGE_SAMPLE_DERIV_COMPARE;
+         ref_or_si = tsrc_swizzle1(coords, ref_pos);
+
+         if (tc->dev->gen < ILO_GEN(7.5))
+            tc_fail(tc, "TXD with shadow sampler not supported");
+      }
+      else {
+         msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_DERIVS;
+      }
 
-      msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_DERIVS;
       ddx = inst->src[1];
       ddy = inst->src[2];
       num_derivs = num_coords;
@@ -457,6 +495,8 @@ vs_prepare_tgsi_sampling(struct toy_compiler *tc, const struct toy_inst *inst,
       break;
    default:
       assert(!"unhandled sampling opcode");
+      if (ret_sampler_index)
+         *ret_sampler_index = 0;
       return tsrc_null();
       break;
    }
@@ -554,6 +594,7 @@ vs_lower_opcode_tgsi_sampling(struct vs_compile_context *vcc,
 
    /* write to a temp first */
    tmp = tc_alloc_tmp(tc);
+   tmp.type = inst->dst.type;
    dst = inst->dst;
    inst->dst = tmp;
 
@@ -831,7 +872,7 @@ vs_collect_outputs(struct vs_compile_context *vcc, struct toy_src *outs)
                }
 
                for (j = first_ucp; j <= last_ucp; j++) {
-                  const int plane_grf = vcc->first_const_grf + j / 2;
+                  const int plane_grf = vcc->first_ucp_grf + j / 2;
                   const int plane_subreg = (j & 1) * 16;
                   const struct toy_src plane = tsrc_rect(tsrc(TOY_FILE_GRF,
                            plane_grf, plane_subreg), TOY_RECT_041);
@@ -1056,21 +1097,31 @@ vs_setup_shader_out(struct ilo_shader *sh, const struct toy_tgsi *tgsi,
 
    /* the first two VUEs are always PSIZE and POSITION */
    num_outs = 2;
+   output_map[0] = psize_slot;
+   output_map[1] = pos_slot;
+
+   sh->out.register_indices[0] =
+      (psize_slot >= 0) ? tgsi->outputs[psize_slot].index : -1;
    sh->out.semantic_names[0] = TGSI_SEMANTIC_PSIZE;
    sh->out.semantic_indices[0] = 0;
+
+   sh->out.register_indices[1] =
+      (pos_slot >= 0) ? tgsi->outputs[pos_slot].index : -1;
    sh->out.semantic_names[1] = TGSI_SEMANTIC_POSITION;
    sh->out.semantic_indices[1] = 0;
 
    sh->out.has_pos = true;
-   output_map[0] = psize_slot;
-   output_map[1] = pos_slot;
 
    /* followed by optional clip distances */
    if (output_clipdist) {
+      sh->out.register_indices[num_outs] =
+         (clipdist_slot[0] >= 0) ? tgsi->outputs[clipdist_slot[0]].index : -1;
       sh->out.semantic_names[num_outs] = TGSI_SEMANTIC_CLIPDIST;
       sh->out.semantic_indices[num_outs] = 0;
       output_map[num_outs++] = clipdist_slot[0];
 
+      sh->out.register_indices[num_outs] =
+         (clipdist_slot[1] >= 0) ? tgsi->outputs[clipdist_slot[1]].index : -1;
       sh->out.semantic_names[num_outs] = TGSI_SEMANTIC_CLIPDIST;
       sh->out.semantic_indices[num_outs] = 1;
       output_map[num_outs++] = clipdist_slot[1];
@@ -1086,6 +1137,7 @@ vs_setup_shader_out(struct ilo_shader *sh, const struct toy_tgsi *tgsi,
       if (slot < 0)
          continue;
 
+      sh->out.register_indices[num_outs] = tgsi->outputs[slot].index;
       sh->out.semantic_names[num_outs] = tgsi->outputs[slot].semantic_name;
       sh->out.semantic_indices[num_outs] = tgsi->outputs[slot].semantic_index;
 
@@ -1102,6 +1154,7 @@ vs_setup_shader_out(struct ilo_shader *sh, const struct toy_tgsi *tgsi,
       case TGSI_SEMANTIC_BCOLOR:
          break;
       default:
+         sh->out.register_indices[num_outs] = tgsi->outputs[i].index;
          sh->out.semantic_names[num_outs] = tgsi->outputs[i].semantic_name;
          sh->out.semantic_indices[num_outs] = tgsi->outputs[i].semantic_index;
          output_map[num_outs++] = i;
@@ -1183,12 +1236,34 @@ vs_setup(struct vs_compile_context *vcc,
    vs_setup_shader_out(vcc->shader, &vcc->tgsi,
          (vcc->variant->u.vs.num_ucps > 0), vcc->output_map);
 
-   /* fit each pair of user clip planes into a register */
-   num_consts = (vcc->variant->u.vs.num_ucps + 1) / 2;
+   if (vcc->variant->use_pcb && !vcc->tgsi.const_indirect) {
+      num_consts = (vcc->tgsi.const_count + 1) / 2;
+
+      /*
+       * From the Sandy Bridge PRM, volume 2 part 1, page 138:
+       *
+       *     "The sum of all four read length fields (each incremented to
+       *      represent the actual read length) must be less than or equal to
+       *      32"
+       */
+      if (num_consts > 32)
+         num_consts = 0;
+   }
+   else {
+      num_consts = 0;
+   }
+
+   vcc->shader->skip_cbuf0_upload = (!vcc->tgsi.const_count || num_consts);
+   vcc->shader->pcb.cbuf0_size = num_consts * (sizeof(float) * 8);
 
    /* r0 is reserved for payload header */
    vcc->first_const_grf = 1;
-   vcc->first_vue_grf = vcc->first_const_grf + num_consts;
+   vcc->first_ucp_grf = vcc->first_const_grf + num_consts;
+
+   /* fit each pair of user clip planes into a register */
+   vcc->first_vue_grf = vcc->first_ucp_grf +
+      (vcc->variant->u.vs.num_ucps + 1) / 2;
+
    vcc->first_free_grf = vcc->first_vue_grf + vcc->shader->in.count;
    vcc->last_free_grf = 127;
 
@@ -1264,7 +1339,7 @@ ilo_shader_compile_vs(const struct ilo_shader_state *state,
 
       if (!ilo_shader_compile_gs_passthrough(state, variant,
                so_mapping, vcc.shader)) {
-         ilo_shader_destroy(vcc.shader);
+         ilo_shader_destroy_kernel(vcc.shader);
          vcc.shader = NULL;
       }
    }