Newer virtual HW versions support smooth/stipple/wide lines.
Use that instead of 'draw' fallbacks when possible.
Reviewed-by: José Fonseca <jfonseca@vmware.com>
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;
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
float slopescaledepthbias;
float depthbias;
float pointsize;
+ float linewidth;
unsigned hw_unfilled:16; /* PIPE_POLYGON_MODE_x */
#include "util/u_memory.h"
#include "svga_context.h"
+#include "svga_screen.h"
#include "svga_hw_reg.h"
{
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;
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";
}
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
}
{
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;
}
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 */
}
}
+ /* 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 {
SVGA3dHardwareVersion hw_version;
+ /** Device caps */
+ boolean haveLineStipple, haveLineSmooth;
+ float maxLineWidth, maxLineWidthAA;
float maxPointSize;
unsigned max_color_buffers;
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))
#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"
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;
/* 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);