llvmpipe: make remove_shader_variant static.
[mesa.git] / src / gallium / drivers / softpipe / sp_state_derived.c
index ca29d76f8c293d93d7fbeafc8b00abd129458164..f34997ab3d0b6114c339dffed7eaf3741a8e61ac 100644 (file)
@@ -63,35 +63,47 @@ static void
 softpipe_compute_vertex_info(struct softpipe_context *softpipe)
 {
    struct sp_setup_info *sinfo = &softpipe->setup_info;
-   int vs_index;
 
    if (sinfo->valid == 0) {
-      /* compute vertex layout for vbuf now */
       const struct tgsi_shader_info *fsInfo = &softpipe->fs_variant->info;
-      struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf;
-      const uint num = draw_num_shader_outputs(softpipe->draw);
+      struct vertex_info *vinfo = &softpipe->vertex_info;
       uint i;
+      int vs_index;
+      /*
+       * This doesn't quite work right (wrt face injection, prim id,
+       * wide points) - hit a couple assertions, misrenderings plus
+       * memory corruption. Albeit could fix (the former two) by calling
+       * this "more often" (rasterizer changes etc.). (The latter would
+       * need to be included in draw_prepare_shader_outputs, but it looks
+       * like that would potentially allocate quite some unused additional
+       * vertex outputs.)
+       * draw_prepare_shader_outputs(softpipe->draw);
+       */
 
-      /* Tell draw_vbuf to simply emit the whole post-xform vertex
-       * as-is.  No longer any need to try and emit draw vertex_header
-       * info.
+      /*
+       * Those can't actually be 0 (because pos is always at 0).
+       * But use ints anyway to avoid confusion (in vs outputs, they
+       * can very well be at pos 0).
        */
-      vinfo_vbuf->num_attribs = 0;
-      for (i = 0; i < num; i++) {
-         draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, i);
-      }
-      draw_compute_vertex_size(vinfo_vbuf);
+      softpipe->viewport_index_slot = -1;
+      softpipe->layer_slot = -1;
+      softpipe->psize_slot = -1;
+
+      vinfo->num_attribs = 0;
+
+      /*
+       * Put position always first (setup needs it there).
+       */
+      vs_index = draw_find_shader_output(softpipe->draw,
+                                         TGSI_SEMANTIC_POSITION, 0);
 
-      softpipe->viewport_index_slot = 0;
-      softpipe->layer_slot = 0;
-      softpipe->psize_slot = 0;
+      draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
 
       /*
-       * Loop over fragment shader inputs, searching for the matching output
-       * from the vertex shader.
+       * Match FS inputs against VS outputs, emitting the necessary
+       * attributes.
        */
       for (i = 0; i < fsInfo->num_inputs; i++) {
-         int src;
          enum sp_interp_mode interp = SP_INTERP_LINEAR;
 
          switch (fsInfo->input_interpolate[i]) {
@@ -126,57 +138,93 @@ softpipe_compute_vertex_info(struct softpipe_context *softpipe)
             break;
          }
 
-         /* this includes texcoords and varying vars */
-         src = draw_find_shader_output(softpipe->draw,
-                                       fsInfo->input_semantic_name[i],
-                                       fsInfo->input_semantic_index[i]);
-         if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_COLOR && src == -1)
+         /*
+          * Search for each input in current vs output:
+          */
+         vs_index = draw_find_shader_output(softpipe->draw,
+                                            fsInfo->input_semantic_name[i],
+                                            fsInfo->input_semantic_index[i]);
+
+         if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_COLOR &&
+             vs_index == -1) {
             /*
              * try and find a bcolor.
              * Note that if there's both front and back color, draw will
              * have copied back to front color already.
              */
-            src = draw_find_shader_output(softpipe->draw,
-                                          TGSI_SEMANTIC_BCOLOR,
-                                          fsInfo->input_semantic_index[i]);
+            vs_index = draw_find_shader_output(softpipe->draw,
+                                               TGSI_SEMANTIC_BCOLOR,
+                                               fsInfo->input_semantic_index[i]);
+         }
 
          sinfo->attrib[i].interp = interp;
+         /* extremely pointless index map */
+         sinfo->attrib[i].src_index = i + 1;
          /*
-          * note src can be -1 if not found. Would need special handling,
-          * (as we don't tell draw anything about it) just force to 0.
-          * It's wrong either way but should be safer...
+          * For vp index and layer, if the fs requires them but the vs doesn't
+          * provide them, draw (vbuf) will give us the required 0 (slot -1).
+          * (This means in this case we'll also use those slots in setup, which
+          * isn't necessary but they'll contain the correct (0) value.)
           */
-         if (src < 0)
-            src = 0;
-         sinfo->attrib[i].src_index = src;
+         if (fsInfo->input_semantic_name[i] ==
+                    TGSI_SEMANTIC_VIEWPORT_INDEX) {
+            softpipe->viewport_index_slot = (int)vinfo->num_attribs;
+            draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
+         } else if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_LAYER) {
+            softpipe->layer_slot = (int)vinfo->num_attribs;
+            draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
+            /*
+             * Note that we'd actually want to skip position (as we won't use
+             * the attribute in the fs) but can't. The reason is that we don't
+             * actually have an input/output map for setup (even though it looks
+             * like we do...). Could adjust for this though even without a map.
+             */
+         } else {
+            /*
+             * Note that we'd actually want to skip position (as we won't use
+             * the attribute in the fs) but can't. The reason is that we don't
+             * actually have an input/output map for setup (even though it looks
+             * like we do...). Could adjust for this though even without a map.
+             */
+            draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
+         }
       }
 
-      /* Figure out if we need pointsize as well. */
+      /* Figure out if we need pointsize as well.
+       */
       vs_index = draw_find_shader_output(softpipe->draw,
                                          TGSI_SEMANTIC_PSIZE, 0);
 
       if (vs_index >= 0) {
-         softpipe->psize_slot = vs_index;
+         softpipe->psize_slot = (int)vinfo->num_attribs;
+         draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
       }
 
-      /* Figure out if we need viewport index */
-      vs_index = draw_find_shader_output(softpipe->draw,
-                                         TGSI_SEMANTIC_VIEWPORT_INDEX,
-                                         0);
-      if (vs_index >= 0) {
-         softpipe->viewport_index_slot = vs_index;
+      /* Figure out if we need viewport index (if it wasn't already in fs input) */
+      if (softpipe->viewport_index_slot < 0) {
+         vs_index = draw_find_shader_output(softpipe->draw,
+                                            TGSI_SEMANTIC_VIEWPORT_INDEX,
+                                            0);
+         if (vs_index >= 0) {
+            softpipe->viewport_index_slot =(int)vinfo->num_attribs;
+            draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
+         }
       }
 
-      /* Figure out if we need layer */
-      vs_index = draw_find_shader_output(softpipe->draw,
-                                         TGSI_SEMANTIC_LAYER,
-                                         0);
-      if (vs_index >= 0) {
-         softpipe->layer_slot = vs_index;
+      /* Figure out if we need layer (if it wasn't already in fs input) */
+      if (softpipe->layer_slot < 0) {
+         vs_index = draw_find_shader_output(softpipe->draw,
+                                            TGSI_SEMANTIC_LAYER,
+                                            0);
+         if (vs_index >= 0) {
+            softpipe->layer_slot = (int)vinfo->num_attribs;
+            draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
+         }
       }
+
+      draw_compute_vertex_size(vinfo);
       softpipe->setup_info.valid = 1;
    }
-
    return;
 }
 
@@ -184,15 +232,14 @@ softpipe_compute_vertex_info(struct softpipe_context *softpipe)
 /**
  * Called from vbuf module.
  *
- * Note the vertex layout used for vbuf is simply telling it to pass
- * through everything as is. The mapping actually used for setup is
- * stored separately (but calculated here too at the same time).
+ * This will trigger validation of the vertex layout (and also compute
+ * the required information for setup).
  */
 struct vertex_info *
 softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe)
 {
    softpipe_compute_vertex_info(softpipe);
-   return &softpipe->vertex_info_vbuf;
+   return &softpipe->vertex_info;
 }
 
 
@@ -235,7 +282,7 @@ compute_cliprect(struct softpipe_context *sp)
 
 static void
 set_shader_sampler(struct softpipe_context *softpipe,
-                   unsigned shader,
+                   enum pipe_shader_type shader,
                    int max_sampler)
 {
    int i;
@@ -245,6 +292,12 @@ set_shader_sampler(struct softpipe_context *softpipe,
    }
 }
 
+void
+softpipe_update_compute_samplers(struct softpipe_context *softpipe)
+{
+   set_shader_sampler(softpipe, PIPE_SHADER_COMPUTE, softpipe->cs->max_sampler);
+}
+
 static void
 update_tgsi_samplers( struct softpipe_context *softpipe )
 {
@@ -260,7 +313,7 @@ update_tgsi_samplers( struct softpipe_context *softpipe )
    }
 
    /* XXX is this really necessary here??? */
-   for (sh = 0; sh < Elements(softpipe->tex_cache); sh++) {
+   for (sh = 0; sh < ARRAY_SIZE(softpipe->tex_cache); sh++) {
       for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
          struct softpipe_tex_tile_cache *tc = softpipe->tex_cache[sh][i];
          if (tc && tc->texture) {
@@ -296,7 +349,9 @@ update_fragment_shader(struct softpipe_context *softpipe, unsigned prim)
       softpipe->fs_variant->prepare(softpipe->fs_variant, 
                                     softpipe->fs_machine,
                                     (struct tgsi_sampler *) softpipe->
-                                    tgsi.sampler[PIPE_SHADER_FRAGMENT]);
+                                    tgsi.sampler[PIPE_SHADER_FRAGMENT],
+                                    (struct tgsi_image *)softpipe->tgsi.image[PIPE_SHADER_FRAGMENT],
+                                    (struct tgsi_buffer *)softpipe->tgsi.buffer[PIPE_SHADER_FRAGMENT]);
    }
    else {
       softpipe->fs_variant = NULL;