svga: expose HW smooth/stipple/wide lines

Newer virtual HW versions support smooth/stipple/wide lines.
Use that instead of 'draw' fallbacks when possible.

Reviewed-by: José Fonseca <jfonseca@vmware.com>
This commit is contained in:
Brian Paul 2013-12-09 10:46:56 -08:00
parent 84b1716b5e
commit ccd6bf8272
7 changed files with 99 additions and 14 deletions

View file

@ -432,8 +432,7 @@ typedef enum {
SVGA3D_RS_DSTBLENDALPHA = 95, /* SVGA3dBlendOp */
SVGA3D_RS_BLENDEQUATIONALPHA = 96, /* SVGA3dBlendEquation */
SVGA3D_RS_TRANSPARENCYANTIALIAS = 97, /* SVGA3dTransparencyAntialiasType */
SVGA3D_RS_LINEAA = 98, /* SVGA3dBool */
SVGA3D_RS_LINEWIDTH = 99, /* float */
SVGA3D_RS_LINEWIDTH = 98, /* float */
SVGA3D_RS_MAX
} SVGA3dRenderStateName;
@ -1879,6 +1878,15 @@ typedef enum {
SVGA3D_DEVCAP_SURFACEFMT_BC4_UNORM = 82,
SVGA3D_DEVCAP_SURFACEFMT_BC5_UNORM = 83,
SVGA3D_DEVCAP_DEAD1 = 84,
SVGA3D_DEVCAP_85 = 85,
SVGA3D_DEVCAP_86 = 86,
SVGA3D_DEVCAP_LINE_AA = 87, /* boolean */
SVGA3D_DEVCAP_LINE_STIPPLE = 88, /* boolean */
SVGA3D_DEVCAP_MAX_LINE_WIDTH = 89, /* float */
SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH = 90, /* float */
/*
* Don't add new caps into the previous section; the values in this
* enumeration must not change. You can put new values right before

View file

@ -160,6 +160,7 @@ struct svga_rasterizer_state {
float slopescaledepthbias;
float depthbias;
float pointsize;
float linewidth;
unsigned hw_unfilled:16; /* PIPE_POLYGON_MODE_x */

View file

@ -30,6 +30,7 @@
#include "util/u_memory.h"
#include "svga_context.h"
#include "svga_screen.h"
#include "svga_hw_reg.h"
@ -66,6 +67,7 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
{
struct svga_context *svga = svga_context(pipe);
struct svga_rasterizer_state *rast = CALLOC_STRUCT( svga_rasterizer_state );
struct svga_screen *screen = svga_screen(pipe->screen);
/* need this for draw module. */
rast->templ = *templ;
@ -100,23 +102,28 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
rast->need_pipeline_tris_str = "poly stipple";
}
if (templ->line_width >= 1.5f &&
!svga->debug.no_line_width) {
if (screen->maxLineWidth > 1.0F) {
/* pass line width to device */
rast->linewidth = MAX2(1.0F, templ->line_width);
}
else if (svga->debug.no_line_width) {
/* nothing */
}
else {
/* use 'draw' pipeline for wide line */
rast->need_pipeline |= SVGA_PIPELINE_FLAG_LINES;
rast->need_pipeline_lines_str = "line width";
}
if (templ->line_stipple_enable) {
/* XXX: LinePattern not implemented on all backends, and there is no
* mechanism to query it.
*/
if (!svga->debug.force_hw_line_stipple) {
if (screen->haveLineStipple || svga->debug.force_hw_line_stipple) {
SVGA3dLinePattern lp;
lp.repeat = templ->line_stipple_factor + 1;
lp.pattern = templ->line_stipple_pattern;
rast->linepattern = lp.uintValue;
}
else {
/* use 'draw' module to decompose into short line segments */
rast->need_pipeline |= SVGA_PIPELINE_FLAG_LINES;
rast->need_pipeline_lines_str = "line stipple";
}
@ -127,9 +134,16 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
rast->need_pipeline_points_str = "smooth points";
}
if (templ->line_smooth) {
if (templ->line_smooth && !screen->haveLineSmooth) {
/*
* XXX: Enabling the pipeline slows down performance immensely, so ignore
* line smooth state, where there is very little visual improvement.
* Smooth lines will still be drawn for wide lines.
*/
#if 0
rast->need_pipeline |= SVGA_PIPELINE_FLAG_LINES;
rast->need_pipeline_lines_str = "smooth lines";
#endif
}
{
@ -228,6 +242,13 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
rast->depthbias = 0;
}
if (0 && rast->need_pipeline) {
debug_printf("svga: rast need_pipeline = 0x%x\n", rast->need_pipeline);
debug_printf(" pnts: %s \n", rast->need_pipeline_points_str);
debug_printf(" lins: %s \n", rast->need_pipeline_lines_str);
debug_printf(" tris: %s \n", rast->need_pipeline_tris_str);
}
return rast;
}

View file

@ -103,9 +103,9 @@ svga_get_paramf(struct pipe_screen *screen, enum pipe_capf param)
switch (param) {
case PIPE_CAPF_MAX_LINE_WIDTH:
/* fall-through */
return svgascreen->maxLineWidth;
case PIPE_CAPF_MAX_LINE_WIDTH_AA:
return 7.0;
return svgascreen->maxLineWidthAA;
case PIPE_CAPF_MAX_POINT_WIDTH:
/* fall-through */
@ -660,6 +660,34 @@ svga_screen_create(struct svga_winsys_screen *sws)
}
}
/* Query device caps
*/
if (!sws->get_cap(sws, SVGA3D_DEVCAP_LINE_STIPPLE, &result))
svgascreen->haveLineStipple = FALSE;
else
svgascreen->haveLineStipple = result.u;
if (!sws->get_cap(sws, SVGA3D_DEVCAP_LINE_AA, &result))
svgascreen->haveLineSmooth = FALSE;
else
svgascreen->haveLineSmooth = result.u;
if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_LINE_WIDTH, &result))
svgascreen->maxLineWidth = 1.0F;
else
svgascreen->maxLineWidth = result.f;
if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH, &result))
svgascreen->maxLineWidthAA = 1.0F;
else
svgascreen->maxLineWidthAA = result.f;
if (0)
debug_printf("svga: haveLineStip %u "
"haveLineSmooth %u maxLineWidth %f\n",
svgascreen->haveLineStipple, svgascreen->haveLineSmooth,
svgascreen->maxLineWidth);
if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_POINT_SIZE, &result)) {
svgascreen->maxPointSize = 1.0F;
} else {

View file

@ -47,6 +47,9 @@ struct svga_screen
SVGA3dHardwareVersion hw_version;
/** Device caps */
boolean haveLineStipple, haveLineSmooth;
float maxLineWidth, maxLineWidthAA;
float maxPointSize;
unsigned max_color_buffers;

View file

@ -221,11 +221,18 @@ emit_rss(struct svga_context *svga, unsigned dirty)
EMIT_RS( svga, curr->scissortestenable, SCISSORTESTENABLE, fail );
EMIT_RS( svga, curr->multisampleantialias, MULTISAMPLEANTIALIAS, fail );
EMIT_RS( svga, curr->lastpixel, LASTPIXEL, fail );
EMIT_RS( svga, curr->linepattern, LINEPATTERN, fail );
EMIT_RS_FLOAT( svga, curr->pointsize, POINTSIZE, fail );
EMIT_RS_FLOAT( svga, point_size_min, POINTSIZEMIN, fail );
EMIT_RS_FLOAT( svga, screen->maxPointSize, POINTSIZEMAX, fail );
EMIT_RS( svga, curr->pointsprite, POINTSPRITEENABLE, fail);
/* Emit line state, when the device understands it */
if (screen->haveLineStipple)
EMIT_RS( svga, curr->linepattern, LINEPATTERN, fail );
if (screen->haveLineSmooth)
EMIT_RS( svga, curr->antialiasedlineenable, ANTIALIASEDLINEENABLE, fail );
if (screen->maxLineWidth > 1.0F)
EMIT_RS_FLOAT( svga, curr->linewidth, LINEWIDTH, fail );
}
if (dirty & (SVGA_NEW_RAST | SVGA_NEW_FRAME_BUFFER | SVGA_NEW_NEED_PIPELINE))

View file

@ -29,6 +29,7 @@
#include "pipe/p_state.h"
#include "svga_context.h"
#include "svga_screen.h"
#include "svga_swtnl.h"
#include "svga_state.h"
#include "svga_swtnl_private.h"
@ -137,6 +138,8 @@ svga_swtnl_draw_vbo(struct svga_context *svga,
boolean svga_init_swtnl( struct svga_context *svga )
{
struct svga_screen *screen = svga_screen(svga->pipe.screen);
svga->swtnl.backend = svga_vbuf_render_create(svga);
if(!svga->swtnl.backend)
goto fail;
@ -161,10 +164,24 @@ boolean svga_init_swtnl( struct svga_context *svga )
/* must be done before installing Draw stages */
util_blitter_cache_all_shaders(svga->blitter);
draw_install_aaline_stage(svga->swtnl.draw, &svga->pipe);
draw_install_aapoint_stage(svga->swtnl.draw, &svga->pipe);
if (!screen->haveLineSmooth)
draw_install_aaline_stage(svga->swtnl.draw, &svga->pipe);
/* always install polygon stipple stage */
draw_install_pstipple_stage(svga->swtnl.draw, &svga->pipe);
/* enable/disable line stipple stage depending on device caps */
draw_enable_line_stipple(svga->swtnl.draw, !screen->haveLineStipple);
/* always install AA point stage */
draw_install_aapoint_stage(svga->swtnl.draw, &svga->pipe);
/* Set wide line threshold above device limit (so we'll never really use it)
*/
draw_wide_line_threshold(svga->swtnl.draw,
MAX2(screen->maxLineWidth,
screen->maxLineWidthAA));
if (debug_get_bool_option("SVGA_SWTNL_FSE", FALSE))
draw_set_driver_clipping(svga->swtnl.draw, TRUE, TRUE, TRUE);