summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2013-12-09 10:46:56 -0800
committerBrian Paul <[email protected]>2013-12-11 17:19:44 -0800
commitccd6bf8272cba7c57e4ae09ab8a03db63472648e (patch)
tree3d3dd8783c41ba50b418a4758e1322badc64363f /src/gallium
parent84b1716b5efa98c21db32ff7f55bb7608d6a11df (diff)
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 <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/svga/include/svga3d_reg.h12
-rw-r--r--src/gallium/drivers/svga/svga_context.h1
-rw-r--r--src/gallium/drivers/svga/svga_pipe_rasterizer.c35
-rw-r--r--src/gallium/drivers/svga/svga_screen.c32
-rw-r--r--src/gallium/drivers/svga/svga_screen.h3
-rw-r--r--src/gallium/drivers/svga/svga_state_rss.c9
-rw-r--r--src/gallium/drivers/svga/svga_swtnl_draw.c21
7 files changed, 99 insertions, 14 deletions
diff --git a/src/gallium/drivers/svga/include/svga3d_reg.h b/src/gallium/drivers/svga/include/svga3d_reg.h
index 05b83c69c6c..464d3267451 100644
--- a/src/gallium/drivers/svga/include/svga3d_reg.h
+++ b/src/gallium/drivers/svga/include/svga3d_reg.h
@@ -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
diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index 284ee2db4a5..dee0cec6460 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -160,6 +160,7 @@ struct svga_rasterizer_state {
float slopescaledepthbias;
float depthbias;
float pointsize;
+ float linewidth;
unsigned hw_unfilled:16; /* PIPE_POLYGON_MODE_x */
diff --git a/src/gallium/drivers/svga/svga_pipe_rasterizer.c b/src/gallium/drivers/svga/svga_pipe_rasterizer.c
index 61e13fae9d9..356898a86e7 100644
--- a/src/gallium/drivers/svga/svga_pipe_rasterizer.c
+++ b/src/gallium/drivers/svga/svga_pipe_rasterizer.c
@@ -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;
}
diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
index 6c2533800d6..330ffdf0e2d 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -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 {
diff --git a/src/gallium/drivers/svga/svga_screen.h b/src/gallium/drivers/svga/svga_screen.h
index 517a3fa844a..b85191c4b26 100644
--- a/src/gallium/drivers/svga/svga_screen.h
+++ b/src/gallium/drivers/svga/svga_screen.h
@@ -47,6 +47,9 @@ struct svga_screen
SVGA3dHardwareVersion hw_version;
+ /** Device caps */
+ boolean haveLineStipple, haveLineSmooth;
+ float maxLineWidth, maxLineWidthAA;
float maxPointSize;
unsigned max_color_buffers;
diff --git a/src/gallium/drivers/svga/svga_state_rss.c b/src/gallium/drivers/svga/svga_state_rss.c
index 51d36b751b8..fb56b3d36ba 100644
--- a/src/gallium/drivers/svga/svga_state_rss.c
+++ b/src/gallium/drivers/svga/svga_state_rss.c
@@ -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))
diff --git a/src/gallium/drivers/svga/svga_swtnl_draw.c b/src/gallium/drivers/svga/svga_swtnl_draw.c
index 0a049569ff7..66e4adfdcbe 100644
--- a/src/gallium/drivers/svga/svga_swtnl_draw.c
+++ b/src/gallium/drivers/svga/svga_swtnl_draw.c
@@ -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);