summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c12
-rw-r--r--src/gallium/auxiliary/draw/draw_context.h3
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_clip.c31
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h2
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c3
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c3
-rw-r--r--src/gallium/docs/source/cso/rasterizer.rst15
-rw-r--r--src/gallium/drivers/svga/svga_swtnl_draw.c2
-rw-r--r--src/gallium/include/pipe/p_state.h1
9 files changed, 60 insertions, 12 deletions
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index 2b3bc0d0ece..9b5bcb5a3be 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -262,6 +262,10 @@ static void update_clip_flags( struct draw_context *draw )
draw->rasterizer && draw->rasterizer->depth_clip);
draw->clip_user = draw->rasterizer &&
draw->rasterizer->clip_plane_enable != 0;
+ draw->clip_points_xy = draw->clip_xy &&
+ (!draw->driver.bypass_clip_points ||
+ (draw->rasterizer &&
+ !draw->rasterizer->point_tri_clip));
}
/**
@@ -287,17 +291,23 @@ void draw_set_rasterizer_state( struct draw_context *draw,
* Some hardware can turn off clipping altogether - in particular any
* hardware with a TNL unit can do its own clipping, even if it is
* relying on the draw module for some other reason.
+ * Setting bypass_clip_points to achieve d3d-style point clipping (the driver
+ * will need to do the "vp scissoring") _requires_ the driver to implement
+ * wide points / point sprites itself (points will still be clipped if rasterizer
+ * point_tri_clip isn't set). Only relevant if bypass_clip_xy isn't set.
*/
void draw_set_driver_clipping( struct draw_context *draw,
boolean bypass_clip_xy,
boolean bypass_clip_z,
- boolean guard_band_xy)
+ boolean guard_band_xy,
+ boolean bypass_clip_points)
{
draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
draw->driver.bypass_clip_xy = bypass_clip_xy;
draw->driver.bypass_clip_z = bypass_clip_z;
draw->driver.guard_band_xy = guard_band_xy;
+ draw->driver.bypass_clip_points = bypass_clip_points;
update_clip_flags(draw);
}
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
index e2e0cb4dad6..65716c93ccc 100644
--- a/src/gallium/auxiliary/draw/draw_context.h
+++ b/src/gallium/auxiliary/draw/draw_context.h
@@ -263,7 +263,8 @@ void draw_set_render( struct draw_context *draw,
void draw_set_driver_clipping( struct draw_context *draw,
boolean bypass_clip_xy,
boolean bypass_clip_z,
- boolean guard_band_xy);
+ boolean guard_band_xy,
+ boolean bypass_clip_points);
void draw_set_force_passthrough( struct draw_context *draw,
boolean enable );
diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c
index dbb67575843..adfa4b6e8b9 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_clip.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c
@@ -609,12 +609,37 @@ do_clip_line( struct draw_stage *stage,
static void
clip_point( struct draw_stage *stage,
- struct prim_header *header )
+ struct prim_header *header )
{
- if (header->v[0]->clipmask == 0)
+ if (header->v[0]->clipmask == 0)
stage->next->point( stage->next, header );
}
+/*
+ * Clip points but ignore the first 4 (xy) clip planes.
+ * (This is necessary because we don't generate a different shader variant
+ * just for points hence xy clip bits are still generated. This is not really
+ * optimal because of the extra calculations both in generating clip masks
+ * and executing the clip stage but it gets the job done.)
+ */
+static void
+clip_point_no_xy( struct draw_stage *stage,
+ struct prim_header *header )
+{
+ if ((header->v[0]->clipmask & 0xfffffff0) == 0)
+ stage->next->point( stage->next, header );
+}
+
+
+
+static void
+clip_first_point( struct draw_stage *stage,
+ struct prim_header *header )
+{
+ stage->point = stage->draw->clip_points_xy ? clip_point : clip_point_no_xy;
+ stage->point(stage, header);
+}
+
static void
clip_line( struct draw_stage *stage,
@@ -822,7 +847,7 @@ struct draw_stage *draw_clip_stage( struct draw_context *draw )
clipper->stage.draw = draw;
clipper->stage.name = "clipper";
- clipper->stage.point = clip_point;
+ clipper->stage.point = clip_first_point;
clipper->stage.line = clip_first_line;
clipper->stage.tri = clip_first_tri;
clipper->stage.flush = clip_flush;
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index fbe25a264c5..5bcb8a8add5 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -217,6 +217,7 @@ struct draw_context
boolean bypass_clip_xy;
boolean bypass_clip_z;
boolean guard_band_xy;
+ boolean bypass_clip_points;
} driver;
boolean quads_always_flatshade_last;
@@ -231,6 +232,7 @@ struct draw_context
boolean clip_z;
boolean clip_user;
boolean guard_band_xy;
+ boolean clip_points_xy;
boolean force_passthrough; /**< never clip or shade */
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
index 8fcc17048d2..ab8a0c6ab39 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
@@ -104,7 +104,8 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
fpme->vertex_size,
instance_id_index );
draw_pt_post_vs_prepare( fpme->post_vs,
- draw->clip_xy,
+ gs_out_prim == PIPE_PRIM_POINTS ?
+ draw->clip_points_xy : draw->clip_xy,
draw->clip_z,
draw->clip_user,
draw->guard_band_xy,
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
index 846e1d58052..bca658f2c05 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
@@ -155,7 +155,8 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
draw_pt_post_vs_prepare( fpme->post_vs,
- draw->clip_xy,
+ out_prim == PIPE_PRIM_POINTS ?
+ draw->clip_points_xy : draw->clip_xy,
draw->clip_z,
draw->clip_user,
draw->guard_band_xy,
diff --git a/src/gallium/docs/source/cso/rasterizer.rst b/src/gallium/docs/source/cso/rasterizer.rst
index 44e5544cdaa..8d473b8446e 100644
--- a/src/gallium/docs/source/cso/rasterizer.rst
+++ b/src/gallium/docs/source/cso/rasterizer.rst
@@ -200,10 +200,11 @@ point_quad_rasterization
Determines if points should be rasterized according to quad or point
rasterization rules.
-OpenGL actually has quite different rasterization rules for points and
-point sprites - hence this indicates if points should be rasterized as
-points or according to point sprite (which decomposes them into quads,
-basically) rules.
+(Legacy-only) OpenGL actually has quite different rasterization rules
+for points and point sprites - hence this indicates if points should be
+rasterized as points or according to point sprite (which decomposes them
+into quads, basically) rules. Newer GL versions no longer support the old
+point rules at all.
Additionally Direct3D will always use quad rasterization rules for
points, regardless of whether point sprites are enabled or not.
@@ -217,6 +218,12 @@ generated.
Some renderers always internally translate points into quads; this state
still affects those renderers by overriding other rasterization state.
+point_tri_clip
+ Determines if clipping of points should happen after they are converted
+ to "rectangles" (required by d3d) or before (required by OpenGL, though
+ this rule is ignored by some IHVs).
+ It is not valid to set this to enabled but have point_quad_rasterization
+ disabled.
point_smooth
Whether points should be smoothed. Point smoothing turns rectangular
points into circles or ovals.
diff --git a/src/gallium/drivers/svga/svga_swtnl_draw.c b/src/gallium/drivers/svga/svga_swtnl_draw.c
index 66e4adfdcbe..de38d6f59f3 100644
--- a/src/gallium/drivers/svga/svga_swtnl_draw.c
+++ b/src/gallium/drivers/svga/svga_swtnl_draw.c
@@ -183,7 +183,7 @@ boolean svga_init_swtnl( struct svga_context *svga )
screen->maxLineWidthAA));
if (debug_get_bool_option("SVGA_SWTNL_FSE", FALSE))
- draw_set_driver_clipping(svga->swtnl.draw, TRUE, TRUE, TRUE);
+ draw_set_driver_clipping(svga->swtnl.draw, TRUE, TRUE, TRUE, FALSE);
return TRUE;
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 1b5f88e3e1d..1ccf3b07d6c 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -99,6 +99,7 @@ struct pipe_rasterizer_state
unsigned point_smooth:1;
unsigned sprite_coord_mode:1; /**< PIPE_SPRITE_COORD_ */
unsigned point_quad_rasterization:1; /** points rasterized as quads or points */
+ unsigned point_tri_clip:1; /** large points clipped as tris or points */
unsigned point_size_per_vertex:1; /**< size computed in vertex shader */
unsigned multisample:1; /* XXX maybe more ms state in future */
unsigned line_smooth:1;