From 29ec116e8f21c65250f1083830b82ff59859496d Mon Sep 17 00:00:00 2001 From: Hui Qi Tay Date: Tue, 10 Aug 2010 11:41:32 +0100 Subject: [PATCH] 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 +- .../drivers/llvmpipe/lp_setup_context.h | 2 + src/gallium/drivers/llvmpipe/lp_setup_point.c | 63 ++++++++++++++++++- .../drivers/llvmpipe/lp_state_derived.c | 20 ++++-- .../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 c52b17b298f..39f2c6085ef 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 778bfb4f6ea..3da9097154e 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 6b041e70713..821ebb1087d 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 7d486afbbf0..877a492c6d8 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 afbc816fb91..6ae318d328d 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 9ef9983307c..edd723f65f2 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 f845a0c6e5c..0bad7320f3e 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; } -- 2.30.2