mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 07:28:11 +02:00
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:
parent
84b1716b5e
commit
ccd6bf8272
7 changed files with 99 additions and 14 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -160,6 +160,7 @@ struct svga_rasterizer_state {
|
|||
float slopescaledepthbias;
|
||||
float depthbias;
|
||||
float pointsize;
|
||||
float linewidth;
|
||||
|
||||
unsigned hw_unfilled:16; /* PIPE_POLYGON_MODE_x */
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@ struct svga_screen
|
|||
|
||||
SVGA3dHardwareVersion hw_version;
|
||||
|
||||
/** Device caps */
|
||||
boolean haveLineStipple, haveLineSmooth;
|
||||
float maxLineWidth, maxLineWidthAA;
|
||||
float maxPointSize;
|
||||
unsigned max_color_buffers;
|
||||
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue