diff options
-rw-r--r-- | src/gallium/auxiliary/draw/draw_context.c | 12 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_context.h | 3 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pipe_clip.c | 31 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_private.h | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 3 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c | 3 | ||||
-rw-r--r-- | src/gallium/docs/source/cso/rasterizer.rst | 15 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_swtnl_draw.c | 2 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_state.h | 1 |
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; |