gallium: rearrange vertex info/layout validation
authorBrian <brian.paul@tungstengraphics.com>
Fri, 15 Feb 2008 01:58:50 +0000 (18:58 -0700)
committerBrian <brian.paul@tungstengraphics.com>
Fri, 15 Feb 2008 01:59:25 +0000 (18:59 -0700)
Delay validation until someone really needs the vertex layout (vbuf alloc
vertex buffer or point/line/tri setup/rendering).
This will allow the vertex size to change depending on whether we're
drawing points, lines or triangles.

src/mesa/pipe/softpipe/sp_prim_setup.c
src/mesa/pipe/softpipe/sp_prim_vbuf.c
src/mesa/pipe/softpipe/sp_state.h
src/mesa/pipe/softpipe/sp_state_derived.c

index 7478b2336b6eac88d5dbd194ba7b2f23cbd5ff65..277204866157d7093c7c7ad62131f66798247fc4 100644 (file)
@@ -499,7 +499,7 @@ setup_fragcoord_coeff(struct setup_stage *setup)
    setup->coef[0].a0[2] = setup->posCoef.a0[2];
    setup->coef[0].dadx[2] = setup->posCoef.dadx[2];
    setup->coef[0].dady[2] = setup->posCoef.dady[2];
-   /*w*/
+   /*W*/
    setup->coef[0].a0[3] = setup->posCoef.a0[3];
    setup->coef[0].dadx[3] = setup->posCoef.dadx[3];
    setup->coef[0].dady[3] = setup->posCoef.dady[3];
@@ -513,8 +513,9 @@ setup_fragcoord_coeff(struct setup_stage *setup)
  */
 static void setup_tri_coefficients( struct setup_stage *setup )
 {
-   const struct softpipe_context *softpipe = setup->softpipe;
+   struct softpipe_context *softpipe = setup->softpipe;
    const struct pipe_shader_state *fs = &softpipe->fs->shader;
+   const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe);
    uint fragSlot;
 
    /* z and w are done by linear interpolation:
@@ -525,10 +526,10 @@ static void setup_tri_coefficients( struct setup_stage *setup )
    /* setup interpolation for all the remaining attributes:
     */
    for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) {
-      const uint vertSlot = softpipe->vertex_info.src_index[fragSlot];
+      const uint vertSlot = vinfo->src_index[fragSlot];
       uint j;
 
-      switch (softpipe->vertex_info.interp_mode[fragSlot]) {
+      switch (vinfo->interp_mode[fragSlot]) {
       case INTERP_CONSTANT:
          for (j = 0; j < NUM_CHANNELS; j++)
             const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
@@ -756,8 +757,9 @@ line_persp_coeff(struct setup_stage *setup,
 static INLINE void
 setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim)
 {
-   const struct softpipe_context *softpipe = setup->softpipe;
+   struct softpipe_context *softpipe = setup->softpipe;
    const struct pipe_shader_state *fs = &setup->softpipe->fs->shader;
+   const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe);
    uint fragSlot;
 
    /* use setup->vmin, vmax to point to vertices */
@@ -779,10 +781,10 @@ setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim)
    /* setup interpolation for all the remaining attributes:
     */
    for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) {
-      const uint vertSlot = softpipe->vertex_info.src_index[fragSlot];
+      const uint vertSlot = vinfo->src_index[fragSlot];
       uint j;
 
-      switch (softpipe->vertex_info.interp_mode[fragSlot]) {
+      switch (vinfo->interp_mode[fragSlot]) {
       case INTERP_CONSTANT:
          for (j = 0; j < NUM_CHANNELS; j++)
             const_coeff(setup, &setup->coef[fragSlot], vertSlot, j);
@@ -978,6 +980,7 @@ setup_point(struct draw_stage *stage, struct prim_header *prim)
    const boolean round = (boolean) setup->softpipe->rasterizer->point_smooth;
    const float x = v0->data[0][0];  /* Note: data[0] is always position */
    const float y = v0->data[0][1];
+   const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe);
    uint fragSlot;
 
    /* For points, all interpolants are constant-valued.
@@ -1003,10 +1006,10 @@ setup_point(struct draw_stage *stage, struct prim_header *prim)
    const_coeff(setup, &setup->posCoef, 0, 3);
 
    for (fragSlot = 0; fragSlot < fs->num_inputs; fragSlot++) {
-      const uint vertSlot = softpipe->vertex_info.src_index[fragSlot];
+      const uint vertSlot = vinfo->src_index[fragSlot];
       uint j;
 
-      switch (softpipe->vertex_info.interp_mode[fragSlot]) {
+      switch (vinfo->interp_mode[fragSlot]) {
       case INTERP_CONSTANT:
          /* fall-through */
       case INTERP_LINEAR:
index c9089e7eb22d838c5446faaa269e7855b6531db7..7f71fdb6a9ac995fe6eeb2a83421fc7c95b8c71b 100644 (file)
@@ -37,6 +37,7 @@
 
 
 #include "sp_context.h"
+#include "sp_state.h"
 #include "sp_prim_vbuf.h"
 #include "pipe/draw/draw_context.h"
 #include "pipe/draw/draw_private.h"
@@ -73,9 +74,7 @@ static const struct vertex_info *
 sp_vbuf_get_vertex_info(struct vbuf_render *vbr)
 {
    struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
-   /* XXX check for state changes? */
-   assert(!cvbr->softpipe->dirty );
-   return &cvbr->softpipe->vertex_info_vbuf;
+   return softpipe_get_vbuf_vertex_info(cvbr->softpipe);
 }
 
 
index af955c1e17b1e3cc638ce66663539b9a88fd8d5c..b79db0d1f199e28290a6e6c235946c99009e57d8 100644 (file)
@@ -59,6 +59,8 @@ struct gallivm_prog;
 #endif
 
 
+struct vertex_info;
+
 
 /** Subclass of pipe_shader_state */
 struct sp_fragment_shader_state {
@@ -174,4 +176,12 @@ softpipe_map_texture_surfaces(struct softpipe_context *sp);
 void
 softpipe_unmap_texture_surfaces(struct softpipe_context *sp);
 
+
+struct vertex_info *
+softpipe_get_vertex_info(struct softpipe_context *softpipe);
+
+struct vertex_info *
+softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe);
+
+
 #endif
index 39c3e1afe1040a48bb36523f31f9878b4903013b..9e4c35e696fa0c89e897aa5d356181ce6d26cfbb 100644 (file)
@@ -49,82 +49,128 @@ find_vs_output(const struct pipe_shader_state *vs,
 }
 
 
+/**
+ * Mark the current vertex layout as "invalid".
+ * We'll validate the vertex layout later, when we start to actually
+ * render a point or line or tri.
+ */
+static void
+invalidate_vertex_layout(struct softpipe_context *softpipe)
+{
+   softpipe->vertex_info.num_attribs =  0;
+}
+
 
 /**
- * Determine how to map vertex program outputs to fragment program inputs.
- * Basically, this will be used when computing the triangle interpolation
- * coefficients from the post-transform vertex attributes.
+ * The vertex info describes how to convert the post-transformed vertices
+ * (simple float[][4]) used by the 'draw' module into vertices for
+ * rasterization.
+ *
+ * This function validates the vertex layout and returns a pointer to a
+ * vertex_info object.
  */
-static void calculate_vertex_layout( struct softpipe_context *softpipe )
+struct vertex_info *
+softpipe_get_vertex_info(struct softpipe_context *softpipe)
 {
-   const struct pipe_shader_state *vs = &softpipe->vs->shader;
-   const struct pipe_shader_state *fs = &softpipe->fs->shader;
-   const enum interp_mode colorInterp
-      = softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
    struct vertex_info *vinfo = &softpipe->vertex_info;
-   uint i;
 
-   if (softpipe->vbuf) {
-      /* if using the post-transform vertex buffer, tell draw_vbuf to
-       * simply emit the whole post-xform vertex as-is:
-       */
-      struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf;
-      vinfo_vbuf->num_attribs = 0;
-      draw_emit_vertex_attr(vinfo_vbuf, EMIT_ALL, INTERP_NONE, 0);
-      vinfo_vbuf->size = 4 * vs->num_outputs + sizeof(struct vertex_header)/4;
-   }
+   if (vinfo->num_attribs == 0) {
+      /* compute vertex layout now */
+      const struct pipe_shader_state *vs = &softpipe->vs->shader;
+      const struct pipe_shader_state *fs = &softpipe->fs->shader;
+      const enum interp_mode colorInterp
+         = softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
+      uint i;
+
+      if (softpipe->vbuf) {
+         /* if using the post-transform vertex buffer, tell draw_vbuf to
+          * simply emit the whole post-xform vertex as-is:
+          */
+         struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf;
+         vinfo_vbuf->num_attribs = 0;
+         draw_emit_vertex_attr(vinfo_vbuf, EMIT_ALL, INTERP_NONE, 0);
+         vinfo_vbuf->size = 4 * vs->num_outputs
+                          + sizeof(struct vertex_header) / 4;
+      }
 
-   /*
-    * Loop over fragment shader inputs, searching for the matching output
-    * from the vertex shader.
-    */
-   vinfo->num_attribs = 0;
-   for (i = 0; i < fs->num_inputs; i++) {
-      int src;
-      switch (fs->input_semantic_name[i]) {
-      case TGSI_SEMANTIC_POSITION:
-         src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0);
-         assert(src >= 0);
-         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src);
-         break;
-
-      case TGSI_SEMANTIC_COLOR:
-         src = find_vs_output(vs, TGSI_SEMANTIC_COLOR, 
-                              fs->input_semantic_index[i]);
-         assert(src >= 0);
-         draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
-         break;
-
-      case TGSI_SEMANTIC_FOG:
-         src = find_vs_output(vs, TGSI_SEMANTIC_FOG, 0);
+      /*
+       * Loop over fragment shader inputs, searching for the matching output
+       * from the vertex shader.
+       */
+      vinfo->num_attribs = 0;
+      for (i = 0; i < fs->num_inputs; i++) {
+         int src;
+         switch (fs->input_semantic_name[i]) {
+         case TGSI_SEMANTIC_POSITION:
+            src = find_vs_output(vs, TGSI_SEMANTIC_POSITION, 0);
+            assert(src >= 0);
+            draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src);
+            break;
+
+         case TGSI_SEMANTIC_COLOR:
+            src = find_vs_output(vs, TGSI_SEMANTIC_COLOR, 
+                                 fs->input_semantic_index[i]);
+            if (src < 0)
+               src = 0;
+            assert(src >= 0);
+            draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
+            break;
+
+         case TGSI_SEMANTIC_FOG:
+            src = find_vs_output(vs, TGSI_SEMANTIC_FOG, 0);
 #if 1
-         if (src < 0) /* XXX temp hack, try demos/fogcoord.c with this */
-            src = 0;
+            if (src < 0) /* XXX temp hack, try demos/fogcoord.c with this */
+               src = 0;
 #endif
-         assert(src >= 0);
-         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
-         break;
-
-      case TGSI_SEMANTIC_GENERIC:
-         /* this includes texcoords and varying vars */
-         src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC,
-                              fs->input_semantic_index[i]);
-         assert(src >= 0);
-         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
-         break;
-
-      default:
-         assert(0);
+            assert(src >= 0);
+            draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
+            break;
+
+         case TGSI_SEMANTIC_GENERIC:
+            /* this includes texcoords and varying vars */
+            src = find_vs_output(vs, TGSI_SEMANTIC_GENERIC,
+                                 fs->input_semantic_index[i]);
+            assert(src >= 0);
+            draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
+            break;
+
+         default:
+            assert(0);
+         }
       }
-   }
 
-   softpipe->psize_slot = find_vs_output(vs, TGSI_SEMANTIC_PSIZE, 0);
-   if (softpipe->psize_slot >= 0) {
-      draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT,
-                            softpipe->psize_slot);
+      softpipe->psize_slot = find_vs_output(vs, TGSI_SEMANTIC_PSIZE, 0);
+      if (softpipe->psize_slot >= 0) {
+         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT,
+                               softpipe->psize_slot);
+      }
+
+      draw_compute_vertex_size(vinfo);
    }
 
-   draw_compute_vertex_size(vinfo);
+   return vinfo;
+}
+
+
+/**
+ * Called from vbuf module.
+ *
+ * Note that there's actually two different vertex layouts in softpipe.
+ *
+ * The normal one is computed in softpipe_get_vertex_info() above and is
+ * used by the point/line/tri "setup" code.
+ *
+ * The other one (this one) is only used by the vbuf module (which is
+ * not normally used by default but used in testing).  For the vbuf module,
+ * we basically want to pass-through the draw module's vertex layout as-is.
+ * When the softpipe vbuf code begins drawing, the normal vertex layout
+ * will come into play again.
+ */
+struct vertex_info *
+softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe)
+{
+   (void) softpipe_get_vertex_info(softpipe);
+   return &softpipe->vertex_info_vbuf;
 }
 
 
@@ -171,7 +217,7 @@ void softpipe_update_derived( struct softpipe_context *softpipe )
    if (softpipe->dirty & (SP_NEW_RASTERIZER |
                           SP_NEW_FS |
                           SP_NEW_VS))
-      calculate_vertex_layout( softpipe );
+      invalidate_vertex_layout( softpipe );
 
    if (softpipe->dirty & (SP_NEW_SCISSOR |
                           SP_NEW_DEPTH_STENCIL_ALPHA |