llvmpipe: point sprites rasterization
authorHui Qi Tay <hqtay@vmware.com>
Tue, 10 Aug 2010 10:41:32 +0000 (11:41 +0100)
committerKeith Whitwell <keithw@vmware.com>
Fri, 27 Aug 2010 12:08:54 +0000 (13:08 +0100)
Point sprites now done in the rasterizer setup code instead of
going through the draw module.

src/gallium/drivers/llvmpipe/lp_context.c
src/gallium/drivers/llvmpipe/lp_setup.c
src/gallium/drivers/llvmpipe/lp_setup.h
src/gallium/drivers/llvmpipe/lp_setup_context.h
src/gallium/drivers/llvmpipe/lp_setup_point.c
src/gallium/drivers/llvmpipe/lp_state_derived.c
src/gallium/drivers/llvmpipe/lp_state_rasterizer.c

index c52b17b298fbdfe908c809efd83790ccd1462b9d..39f2c6085ef0665fa0db47c233f1ee3058bac18a 100644 (file)
@@ -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);
 
index 778bfb4f6ea8597c9ffe1f70351106aca9b3086f..3da9097154ef630a918087e6ac8cc882cf398c57 100644 (file)
@@ -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
index 6b041e7071345a467ed46bae4ca5215475170892..821ebb1087dcd70f4a33942facfcce9963ee06ae 100644 (file)
@@ -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,
index 7d486afbbf08ffc1ea18c69f73d058ad49d0b51c..877a492c6d8e30190541816a37fb6f4718dc687a 100644 (file)
@@ -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;
index afbc816fb915a4600db945ffd7084594cc2622a9..6ae318d328df425b62b067b2f71874fafe7d7b95 100644 (file)
@@ -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 
index 9ef9983307cddbcc3575f002ba357eca35e3d28d..edd723f65f28700bad18f187bb340efa1d3a708b 100644 (file)
@@ -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;
index f845a0c6e5cc3629ff457b9d293302af2fb53e69..0bad7320f3ef30699357849e54f26b8d57d24c1e 100644 (file)
@@ -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;
 }