summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHui Qi Tay <hqtay@vmware.com>2010-08-10 11:41:32 +0100
committerKeith Whitwell <keithw@vmware.com>2010-08-27 10:59:12 +0100
commit417bb515c76e7a5dd577766fe1190545c24a1dbc (patch)
tree192446a8654449e8ef1479601963e2818d03db8c
parent4d26c830a0f81978266dfada9a7ac0718c8f3135 (diff)
llvmpipe: point sprites rasterization
Point sprites now done in the rasterizer setup code instead of going through the draw module.
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.h4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_context.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_point.c63
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_derived.c20
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_rasterizer.c6
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 c52b17b298..39f2c6085e 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 778bfb4f6e..3da9097154 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 6b041e7071..821ebb1087 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 7d486afbbf..877a492c6d 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 afbc816fb9..6ae318d328 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 9ef9983307..edd723f65f 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 f845a0c6e5..0bad7320f3 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;
}