summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian <brian.paul@tungstengraphics.com>2007-10-22 11:59:26 -0600
committerBrian <brian.paul@tungstengraphics.com>2007-10-22 11:59:26 -0600
commit22e5c4f0f09cff64039b171c5cee6def07395e1f (patch)
treefc1812c0655ab977729b45c2851e4af2b62d3191
parentcd4d732773e06e462e78b8f5bc9f3f1552a198ac (diff)
implement point sprite mode
-rw-r--r--src/mesa/pipe/draw/draw_validate.c3
-rw-r--r--src/mesa/pipe/draw/draw_wide_prims.c80
2 files changed, 48 insertions, 35 deletions
diff --git a/src/mesa/pipe/draw/draw_validate.c b/src/mesa/pipe/draw/draw_validate.c
index 5ec581d8b3..fdeb1be8ca 100644
--- a/src/mesa/pipe/draw/draw_validate.c
+++ b/src/mesa/pipe/draw/draw_validate.c
@@ -52,7 +52,8 @@ static void validate_begin( struct draw_stage *stage )
*/
if (draw->rasterizer->line_width != 1.0 ||
- draw->rasterizer->point_size != 1.0) {
+ draw->rasterizer->point_size != 1.0 ||
+ draw->rasterizer->point_sprite) {
draw->pipeline.wide->next = next;
next = draw->pipeline.wide;
}
diff --git a/src/mesa/pipe/draw/draw_wide_prims.c b/src/mesa/pipe/draw/draw_wide_prims.c
index e7e90fabae..0d02e70814 100644
--- a/src/mesa/pipe/draw/draw_wide_prims.c
+++ b/src/mesa/pipe/draw/draw_wide_prims.c
@@ -39,6 +39,9 @@ struct wide_stage {
float half_line_width;
float half_point_size;
+
+ uint texcoord[PIPE_MAX_SHADER_OUTPUTS];
+ uint num_texcoords;
};
@@ -120,10 +123,30 @@ static void wide_line( struct draw_stage *stage,
}
+static void set_texcoords(const struct wide_stage *wide,
+ struct vertex_header *v, const float tc[4])
+{
+ uint i;
+ for (i = 0; i < wide->num_texcoords; i++) {
+ uint j = wide->texcoord[i];
+ v->data[j][0] = tc[0];
+ v->data[j][1] = tc[1];
+ v->data[j][2] = tc[2];
+ v->data[j][3] = tc[3];
+ }
+}
+
+
+/* If there are lots of sprite points (and why wouldn't there be?) it
+ * would probably be more sensible to change hardware setup to
+ * optimize this rather than doing the whole thing in software like
+ * this.
+ */
static void wide_point( struct draw_stage *stage,
struct prim_header *header )
{
const struct wide_stage *wide = wide_stage(stage);
+ const boolean sprite = stage->draw->rasterizer->point_sprite;
float half_size = wide->half_point_size;
float left_adj, right_adj;
@@ -155,6 +178,17 @@ static void wide_point( struct draw_stage *stage,
pos3[0] += right_adj;
pos3[1] += half_size;
+ if (sprite) {
+ static const float tex00[4] = { 0, 0, 0, 1 };
+ static const float tex01[4] = { 0, 1, 0, 1 };
+ static const float tex11[4] = { 1, 1, 0, 1 };
+ static const float tex10[4] = { 1, 0, 0, 1 };
+ set_texcoords( wide, v0, tex00 );
+ set_texcoords( wide, v1, tex01 );
+ set_texcoords( wide, v2, tex10 );
+ set_texcoords( wide, v3, tex11 );
+ }
+
tri.det = header->det; /* only the sign matters */
tri.v[0] = v0;
tri.v[1] = v2;
@@ -168,36 +202,6 @@ static void wide_point( struct draw_stage *stage,
}
-/* If there are lots of sprite points (and why wouldn't there be?) it
- * would probably be more sensible to change hardware setup to
- * optimize this rather than doing the whole thing in software like
- * this.
- */
-static void sprite_point( struct draw_stage *stage,
- struct prim_header *header )
-{
-#if 0
- struct vertex_header *v[4];
- struct vertex_fetch *vf = stage->pipe->draw->vb.vf;
-
- static const float tex00[4] = { 0, 0, 0, 1 };
- static const float tex01[4] = { 0, 1, 0, 1 };
- static const float tex11[4] = { 1, 1, 0, 1 };
- static const float tex10[4] = { 1, 0, 0, 1 };
-
- make_wide_point(stage, header->v[0], &v[0] );
-
- set_texcoord( vf, v[0], tex00 );
- set_texcoord( vf, v[1], tex01 );
- set_texcoord( vf, v[2], tex10 );
- set_texcoord( vf, v[3], tex11 );
-
- quad( stage->next, v[0], v[1], v[2], v[3] );
-#endif
-}
-
-
-
static void wide_begin( struct draw_stage *stage )
{
struct wide_stage *wide = wide_stage(stage);
@@ -213,16 +217,24 @@ static void wide_begin( struct draw_stage *stage )
wide->stage.line = passthrough_line;
}
- if (0/*draw->state.point_sprite*/) {
- wide->stage.point = sprite_point;
- }
- else if (draw->rasterizer->point_size != 1.0) {
+ if (draw->rasterizer->point_size != 1.0) {
wide->stage.point = wide_point;
}
else {
wide->stage.point = passthrough_point;
}
+ if (draw->rasterizer->point_sprite) {
+ /* find vertex shader texcoord outputs */
+ const struct draw_vertex_shader *vs = draw->vertex_shader;
+ uint i, j = 0;
+ for (i = 0; i < vs->state->num_outputs; i++) {
+ if (vs->state->output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) {
+ wide->texcoord[j++] = i;
+ }
+ }
+ wide->num_texcoords = j;
+ }
stage->next->begin( stage->next );
}