Mesa (master): llvmpipe: point sprites rasterization

Keith Whitwell keithw at kemper.freedesktop.org
Fri Aug 27 12:14:08 UTC 2010


Module: Mesa
Branch: master
Commit: 29ec116e8f21c65250f1083830b82ff59859496d
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=29ec116e8f21c65250f1083830b82ff59859496d

Author: Hui Qi Tay <hqtay at vmware.com>
Date:   Tue Aug 10 11:41:32 2010 +0100

llvmpipe: point sprites rasterization

Point sprites now done in the rasterizer setup code instead of
going through the draw module.

---

 src/gallium/drivers/llvmpipe/lp_context.c          |    2 +
 src/gallium/drivers/llvmpipe/lp_setup.c            |    6 ++-
 src/gallium/drivers/llvmpipe/lp_setup.h            |    4 +-
 src/gallium/drivers/llvmpipe/lp_setup_context.h    |    2 +
 src/gallium/drivers/llvmpipe/lp_setup_point.c      |   63 +++++++++++++++++++-
 src/gallium/drivers/llvmpipe/lp_state_derived.c    |   20 +++++--
 src/gallium/drivers/llvmpipe/lp_state_rasterizer.c |    6 +-
 7 files changed, 93 insertions(+), 10 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c
index c52b17b..39f2c60 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.c
+++ b/src/gallium/drivers/llvmpipe/lp_context.c
@@ -158,6 +158,8 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
    /* convert points and lines into triangles: 
     * (otherwise, draw points and lines natively)
     */
+   draw_wide_point_sprites(llvmpipe->draw, FALSE);
+   draw_enable_point_sprites(llvmpipe->draw, FALSE);
    draw_wide_point_threshold(llvmpipe->draw, 10000.0);
    draw_wide_line_threshold(llvmpipe->draw, 10000.0);
 
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index 778bfb4..3da9097 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -496,11 +496,15 @@ lp_setup_set_line_state( struct lp_setup_context *setup,
 
 void 
 lp_setup_set_point_state( struct lp_setup_context *setup,
-                          float point_size)
+                          float point_size,                          
+                          boolean point_size_per_vertex,
+                          uint sprite)
 {
    LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
 
    setup->point_size = point_size;
+   setup->sprite = sprite;
+   setup->point_size_per_vertex = point_size_per_vertex;
 }
 
 void
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h
index 6b041e7..821ebb1 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup.h
@@ -106,7 +106,9 @@ lp_setup_set_line_state( struct lp_setup_context *setup,
 
 void 
 lp_setup_set_point_state( struct lp_setup_context *setup,
-                          float point_size);
+                          float point_size,                          
+                          boolean point_size_per_vertex,
+                          uint sprite);
 
 void
 lp_setup_set_fs_inputs( struct lp_setup_context *setup,
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h
index 7d486af..877a492 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h
@@ -74,6 +74,7 @@ struct lp_setup_context
    uint prim;
    uint vertex_size;
    uint nr_vertices;
+   uint sprite;
    uint vertex_buffer_size;
    void *vertex_buffer;
 
@@ -89,6 +90,7 @@ struct lp_setup_context
    boolean flatshade_first;
    boolean ccw_is_frontface;
    boolean scissor_test;
+   boolean point_size_per_vertex;
    unsigned cullmode;
    float pixel_offset;
    float line_width;
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_point.c b/src/gallium/drivers/llvmpipe/lp_setup_point.c
index afbc816..6ae318d 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_point.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_point.c
@@ -36,6 +36,7 @@
 #include "lp_setup_context.h"
 #include "lp_rast.h"
 #include "lp_state_fs.h"
+#include "tgsi/tgsi_scan.h"
 
 #define NUM_CHANNELS 4
 
@@ -62,6 +63,49 @@ static void constant_coef( struct lp_setup_context *setup,
    point->inputs.dady[slot][i] = 0.0f;
 }
 
+static void perspective_coef( struct lp_setup_context *setup,
+                              struct lp_rast_triangle *point,
+                              const struct point_info *info,
+                              unsigned slot,
+                              unsigned vert_attr,
+                              unsigned i)
+{
+   if (i == 0) {   
+      float dadx = FIXED_ONE / (float)info->dx12;  
+      float dady =  0.0f;
+      point->inputs.dadx[slot][i] = dadx;
+      point->inputs.dady[slot][i] = dady;
+      point->inputs.a0[slot][i] = (0.5 -
+                                  (dadx * ((float)info->v0[0][0] - setup->pixel_offset) +
+                                   dady * ((float)info->v0[0][1] - setup->pixel_offset)));
+   }
+
+   else if (i == 1) {
+      float dadx =  0.0f; 
+      float dady =  FIXED_ONE / (float)info->dx12;
+   
+      point->inputs.dadx[slot][i] = dadx;
+      point->inputs.dady[slot][i] = dady;
+      point->inputs.a0[slot][i] = (0.5 -
+                                  (dadx * ((float)info->v0[0][0] - setup->pixel_offset) +
+                                   dady * ((float)info->v0[0][1] - setup->pixel_offset)));
+   }
+
+   else if (i == 2) {
+      point->inputs.a0[slot][i] = 0.0f;
+      point->inputs.dadx[slot][i] = 0.0f;
+      point->inputs.dady[slot][i] = 0.0f;
+   }
+      
+   else if (i == 3) {
+      point->inputs.a0[slot][i] = 1.0f;
+      point->inputs.dadx[slot][i] = 0.0f;
+      point->inputs.dady[slot][i] = 0.0f;
+   }
+
+}
+
+
 /**
  * Special coefficient setup for gl_FragCoord.
  * X and Y are trivial
@@ -128,6 +172,23 @@ setup_point_coefficients( struct lp_setup_context *setup,
          fragcoord_usage_mask |= usage_mask;
          break;
 
+      case LP_INTERP_PERSPECTIVE:
+         /* For point sprite textures */        
+         if (setup->fs.current.variant->shader->info.input_semantic_name[slot] 
+             == TGSI_SEMANTIC_GENERIC) 
+         {
+            int index = setup->fs.current.variant->shader->info.input_semantic_index[slot];
+            
+            if (setup->sprite & (1 << index)) {
+               for (i = 0; i < NUM_CHANNELS; i++)
+                  if (usage_mask & (1 << i))
+                     perspective_coef(setup, point, info, slot+1, vert_attr, i);
+               fragcoord_usage_mask |= TGSI_WRITEMASK_W;
+               break;                     
+            }
+         }
+
+         /* Otherwise fallthrough */
       default:
          for (i = 0; i < NUM_CHANNELS; i++) {
             if (usage_mask & (1 << i))
@@ -155,7 +216,7 @@ static void lp_setup_point( struct lp_setup_context *setup,
    /* x/y positions in fixed point */
    const int sizeAttr = setup->psize;
    const float size
-      = sizeAttr > 0 ? v0[sizeAttr][0]
+      = (setup->point_size_per_vertex && sizeAttr > 0) ? v0[sizeAttr][0]
       : setup->point_size;
    
    /* Point size as fixed point integer, remove rounding errors 
diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c
index 9ef9983..edd723f 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_derived.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c
@@ -74,6 +74,15 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe)
       vs_index = draw_find_shader_output(llvmpipe->draw,
                                          lpfs->info.input_semantic_name[i],
                                          lpfs->info.input_semantic_index[i]);
+      if (vs_index < 0) {
+         /*
+          * This can happen with sprite coordinates - the vertex
+          * shader doesn't need to provide an output as we generate
+          * them internally.  However, lets keep pretending that there
+          * is something there to not confuse other code.
+          */
+         vs_index = 0;
+      }
 
       /* This can be pre-computed, except for flatshade:
        */
@@ -128,11 +137,12 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe)
 
    /* Figure out if we need pointsize as well.
     */
-   llvmpipe->psize_slot = draw_find_shader_output(llvmpipe->draw,
-                                                  TGSI_SEMANTIC_PSIZE, 0);
-   if (llvmpipe->psize_slot > 0) {
-      draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT,
-                            llvmpipe->psize_slot);
+   vs_index = draw_find_shader_output(llvmpipe->draw,
+                                      TGSI_SEMANTIC_PSIZE, 0);
+
+   if (vs_index > 0) {
+      llvmpipe->psize_slot = vinfo->num_attribs;
+      draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
    }
 
    llvmpipe->num_inputs = lpfs->info.num_inputs;
diff --git a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
index f845a0c..0bad732 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
@@ -76,8 +76,10 @@ llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, void *handle)
       lp_setup_set_line_state( llvmpipe->setup,
                    llvmpipe->rasterizer->line_width);
       lp_setup_set_point_state( llvmpipe->setup,
-                   llvmpipe->rasterizer->point_size);
-   }
+                   llvmpipe->rasterizer->point_size,
+                   llvmpipe->rasterizer->point_size_per_vertex,
+                   llvmpipe->rasterizer->sprite_coord_enable);
+       }
 
    llvmpipe->dirty |= LP_NEW_RASTERIZER;
 }




More information about the mesa-commit mailing list