mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 09:38:07 +02:00
svga: disable rasterization if rasterizer_discard is set or FS undefined
With this patch, rasterization will be disabled if the
rasterizer_discard flag is set or the fragment shader
is undefined due to missing position output from the
vertex/geometry shader.
Tested with piglit test glsl-1.50-geometry-primitive-id-restart.
Also tested with full MTT glretrace and piglit.
v2: As suggested by Roland, to properly disable rasterization, besides
setting FS to NULL, we will also need to disable depth and stencil test.
v3: As suggested by Brian, set SVGA_NEW_DEPTH_STENCIL_ALPHA dirty bit
in svga_bind_rasterizer_state() if the rasterizer_discard flag is
changed.
Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
parent
fed72ff6cb
commit
b4c4ee0762
6 changed files with 129 additions and 40 deletions
|
|
@ -67,6 +67,11 @@ svga_destroy(struct pipe_context *pipe)
|
|||
}
|
||||
}
|
||||
|
||||
/* free depthstencil_disable state */
|
||||
if (svga->depthstencil_disable) {
|
||||
pipe->delete_depth_stencil_alpha_state(pipe, svga->depthstencil_disable);
|
||||
}
|
||||
|
||||
/* free HW constant buffers */
|
||||
for (shader = 0; shader < ARRAY_SIZE(svga->state.hw_draw.constbuf); shader++) {
|
||||
pipe_resource_reference(&svga->state.hw_draw.constbuf[shader], NULL);
|
||||
|
|
@ -248,6 +253,7 @@ svga_context_create(struct pipe_screen *screen, void *priv, unsigned flags)
|
|||
svga->state.hw_draw.num_views = 0;
|
||||
svga->state.hw_draw.num_rendertargets = 0;
|
||||
svga->state.hw_draw.dsv = NULL;
|
||||
svga->state.hw_draw.rasterizer_discard = FALSE;
|
||||
|
||||
/* Initialize the shader pointers */
|
||||
svga->state.hw_draw.vs = NULL;
|
||||
|
|
@ -289,6 +295,7 @@ svga_context_create(struct pipe_screen *screen, void *priv, unsigned flags)
|
|||
|
||||
svga->dirty = ~0;
|
||||
svga->pred.query_id = SVGA3D_INVALID_ID;
|
||||
svga->disable_rasterizer = FALSE;
|
||||
|
||||
return &svga->pipe;
|
||||
|
||||
|
|
|
|||
|
|
@ -399,6 +399,8 @@ struct svga_hw_draw_state
|
|||
|
||||
/* used for rebinding */
|
||||
unsigned default_constbuf_size[PIPE_SHADER_TYPES];
|
||||
|
||||
boolean rasterizer_discard; /* set if rasterization is disabled */
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -583,6 +585,9 @@ struct svga_context
|
|||
/** Alternate rasterizer states created for point sprite */
|
||||
struct svga_rasterizer_state *rasterizer_no_cull[2];
|
||||
|
||||
/** Depth stencil state created to disable depth stencil test */
|
||||
struct svga_depth_stencil_state *depthstencil_disable;
|
||||
|
||||
/** Current conditional rendering predicate */
|
||||
struct {
|
||||
SVGA3dQueryId query_id;
|
||||
|
|
@ -590,6 +595,7 @@ struct svga_context
|
|||
} pred;
|
||||
|
||||
boolean render_condition;
|
||||
boolean disable_rasterizer; /* Set if to disable rasterization */
|
||||
};
|
||||
|
||||
/* A flag for each state_tracker state object:
|
||||
|
|
|
|||
|
|
@ -45,6 +45,16 @@
|
|||
#include "svga_debug.h"
|
||||
#include "svga_resource_buffer.h"
|
||||
|
||||
/* Returns TRUE if we are currently using flat shading.
|
||||
*/
|
||||
static boolean
|
||||
is_using_flat_shading(const struct svga_context *svga)
|
||||
{
|
||||
return
|
||||
svga->state.hw_draw.fs ? svga->state.hw_draw.fs->uses_flat_interp : FALSE;
|
||||
}
|
||||
|
||||
|
||||
static enum pipe_error
|
||||
retry_draw_range_elements( struct svga_context *svga,
|
||||
struct pipe_resource *index_buffer,
|
||||
|
|
@ -74,7 +84,7 @@ retry_draw_range_elements( struct svga_context *svga,
|
|||
*/
|
||||
svga_hwtnl_set_flatshade(svga->hwtnl,
|
||||
svga->curr.rast->templ.flatshade ||
|
||||
svga->state.hw_draw.fs->uses_flat_interp,
|
||||
is_using_flat_shading(svga),
|
||||
svga->curr.rast->templ.flatshade_first);
|
||||
|
||||
ret = svga_hwtnl_draw_range_elements( svga->hwtnl,
|
||||
|
|
@ -126,7 +136,7 @@ retry_draw_arrays( struct svga_context *svga,
|
|||
*/
|
||||
svga_hwtnl_set_flatshade(svga->hwtnl,
|
||||
svga->curr.rast->templ.flatshade ||
|
||||
svga->state.hw_draw.fs->uses_flat_interp,
|
||||
is_using_flat_shading(svga),
|
||||
svga->curr.rast->templ.flatshade_first);
|
||||
|
||||
ret = svga_hwtnl_draw_arrays(svga->hwtnl, prim, start, count,
|
||||
|
|
|
|||
|
|
@ -378,11 +378,18 @@ svga_bind_rasterizer_state(struct pipe_context *pipe, void *state)
|
|||
struct svga_context *svga = svga_context(pipe);
|
||||
struct svga_rasterizer_state *raster = (struct svga_rasterizer_state *)state;
|
||||
|
||||
if (!raster ||
|
||||
!svga->curr.rast ||
|
||||
raster->templ.poly_stipple_enable !=
|
||||
svga->curr.rast->templ.poly_stipple_enable) {
|
||||
svga->dirty |= SVGA_NEW_STIPPLE;
|
||||
if (!raster || !svga->curr.rast) {
|
||||
svga->dirty |= SVGA_NEW_STIPPLE | SVGA_NEW_DEPTH_STENCIL_ALPHA;
|
||||
}
|
||||
else {
|
||||
if (raster->templ.poly_stipple_enable !=
|
||||
svga->curr.rast->templ.poly_stipple_enable) {
|
||||
svga->dirty |= SVGA_NEW_STIPPLE;
|
||||
}
|
||||
if (raster->templ.rasterizer_discard !=
|
||||
svga->curr.rast->templ.rasterizer_discard) {
|
||||
svga->dirty |= SVGA_NEW_DEPTH_STENCIL_ALPHA;
|
||||
}
|
||||
}
|
||||
|
||||
svga->curr.rast = raster;
|
||||
|
|
|
|||
|
|
@ -408,6 +408,27 @@ emit_hw_fs(struct svga_context *svga, unsigned dirty)
|
|||
|
||||
SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_EMITFS);
|
||||
|
||||
/* Disable rasterization if rasterizer_discard flag is set or
|
||||
* vs/gs does not output position.
|
||||
*/
|
||||
svga->disable_rasterizer =
|
||||
svga->curr.rast->templ.rasterizer_discard ||
|
||||
(svga->curr.gs && !svga->curr.gs->base.info.writes_position) ||
|
||||
(!svga->curr.gs && !svga->curr.vs->base.info.writes_position);
|
||||
|
||||
/* Set FS to NULL when rasterization is to be disabled */
|
||||
if (svga->disable_rasterizer) {
|
||||
/* Set FS to NULL if it has not been done */
|
||||
if (svga->state.hw_draw.fs) {
|
||||
ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_PS, NULL);
|
||||
if (ret != PIPE_OK)
|
||||
goto done;
|
||||
}
|
||||
svga->rebind.flags.fs = FALSE;
|
||||
svga->state.hw_draw.fs = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* SVGA_NEW_BLEND
|
||||
* SVGA_NEW_TEXTURE_BINDING
|
||||
* SVGA_NEW_RAST
|
||||
|
|
|
|||
|
|
@ -336,6 +336,21 @@ get_no_cull_rasterizer_state(struct svga_context *svga)
|
|||
return svga->rasterizer_no_cull[aa_point];
|
||||
}
|
||||
|
||||
|
||||
/** Returns a depth stencil state object with depth and stencil test disabled.
|
||||
*/
|
||||
static struct svga_depth_stencil_state *
|
||||
get_no_depth_stencil_test_state(struct svga_context *svga)
|
||||
{
|
||||
if (!svga->depthstencil_disable) {
|
||||
struct pipe_depth_stencil_alpha_state ds = {{0}};
|
||||
svga->depthstencil_disable =
|
||||
svga->pipe.create_depth_stencil_alpha_state(&svga->pipe, &ds);
|
||||
}
|
||||
return svga->depthstencil_disable;
|
||||
}
|
||||
|
||||
|
||||
static enum pipe_error
|
||||
emit_rss_vgpu10(struct svga_context *svga, unsigned dirty)
|
||||
{
|
||||
|
|
@ -394,45 +409,67 @@ emit_rss_vgpu10(struct svga_context *svga, unsigned dirty)
|
|||
}
|
||||
}
|
||||
|
||||
if (dirty & (SVGA_NEW_DEPTH_STENCIL_ALPHA | SVGA_NEW_STENCIL_REF)) {
|
||||
const struct svga_depth_stencil_state *curr = svga->curr.depth;
|
||||
unsigned curr_ref = svga->curr.stencil_ref.ref_value[0];
|
||||
if (svga->disable_rasterizer) {
|
||||
if (!svga->state.hw_draw.rasterizer_discard) {
|
||||
struct svga_depth_stencil_state *ds;
|
||||
|
||||
if (curr->id != svga->state.hw_draw.depth_stencil_id ||
|
||||
curr_ref != svga->state.hw_draw.stencil_ref) {
|
||||
/* Set/bind the depth/stencil state object */
|
||||
ret = SVGA3D_vgpu10_SetDepthStencilState(svga->swc, curr->id,
|
||||
curr_ref);
|
||||
if (ret != PIPE_OK)
|
||||
return ret;
|
||||
|
||||
svga->state.hw_draw.depth_stencil_id = curr->id;
|
||||
svga->state.hw_draw.stencil_ref = curr_ref;
|
||||
}
|
||||
}
|
||||
|
||||
if (dirty & (SVGA_NEW_REDUCED_PRIMITIVE | SVGA_NEW_RAST)) {
|
||||
const struct svga_rasterizer_state *rast;
|
||||
|
||||
if (svga->curr.reduced_prim == PIPE_PRIM_POINTS &&
|
||||
svga->curr.gs && svga->curr.gs->wide_point) {
|
||||
|
||||
/* If we are drawing a point sprite, we will need to
|
||||
* bind a non-culling rasterizer state object
|
||||
/* If rasterization is to be disabled, disable depth and stencil
|
||||
* testing as well.
|
||||
*/
|
||||
rast = get_no_cull_rasterizer_state(svga);
|
||||
ds = get_no_depth_stencil_test_state(svga);
|
||||
if (ds->id != svga->state.hw_draw.depth_stencil_id) {
|
||||
ret = SVGA3D_vgpu10_SetDepthStencilState(svga->swc, ds->id, 0);
|
||||
if (ret != PIPE_OK)
|
||||
return ret;
|
||||
|
||||
svga->state.hw_draw.depth_stencil_id = ds->id;
|
||||
svga->state.hw_draw.stencil_ref = 0;
|
||||
}
|
||||
svga->state.hw_draw.rasterizer_discard = TRUE;
|
||||
}
|
||||
else {
|
||||
rast = svga->curr.rast;
|
||||
} else {
|
||||
if ((dirty & (SVGA_NEW_DEPTH_STENCIL_ALPHA | SVGA_NEW_STENCIL_REF)) ||
|
||||
svga->state.hw_draw.rasterizer_discard) {
|
||||
const struct svga_depth_stencil_state *curr = svga->curr.depth;
|
||||
unsigned curr_ref = svga->curr.stencil_ref.ref_value[0];
|
||||
|
||||
if (curr->id != svga->state.hw_draw.depth_stencil_id ||
|
||||
curr_ref != svga->state.hw_draw.stencil_ref) {
|
||||
/* Set/bind the depth/stencil state object */
|
||||
ret = SVGA3D_vgpu10_SetDepthStencilState(svga->swc, curr->id,
|
||||
curr_ref);
|
||||
if (ret != PIPE_OK)
|
||||
return ret;
|
||||
|
||||
svga->state.hw_draw.depth_stencil_id = curr->id;
|
||||
svga->state.hw_draw.stencil_ref = curr_ref;
|
||||
}
|
||||
}
|
||||
|
||||
if (svga->state.hw_draw.rasterizer_id != rast->id) {
|
||||
/* Set/bind the rasterizer state object */
|
||||
ret = SVGA3D_vgpu10_SetRasterizerState(svga->swc, rast->id);
|
||||
if (ret != PIPE_OK)
|
||||
return ret;
|
||||
svga->state.hw_draw.rasterizer_id = rast->id;
|
||||
if (dirty & (SVGA_NEW_REDUCED_PRIMITIVE | SVGA_NEW_RAST)) {
|
||||
const struct svga_rasterizer_state *rast;
|
||||
|
||||
if (svga->curr.reduced_prim == PIPE_PRIM_POINTS &&
|
||||
svga->curr.gs && svga->curr.gs->wide_point) {
|
||||
|
||||
/* If we are drawing a point sprite, we will need to
|
||||
* bind a non-culling rasterizer state object
|
||||
*/
|
||||
rast = get_no_cull_rasterizer_state(svga);
|
||||
}
|
||||
else {
|
||||
rast = svga->curr.rast;
|
||||
}
|
||||
|
||||
if (svga->state.hw_draw.rasterizer_id != rast->id) {
|
||||
/* Set/bind the rasterizer state object */
|
||||
ret = SVGA3D_vgpu10_SetRasterizerState(svga->swc, rast->id);
|
||||
if (ret != PIPE_OK)
|
||||
return ret;
|
||||
svga->state.hw_draw.rasterizer_id = rast->id;
|
||||
}
|
||||
}
|
||||
svga->state.hw_draw.rasterizer_discard = FALSE;
|
||||
}
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
|
@ -461,6 +498,7 @@ struct svga_tracked_state svga_hw_rss =
|
|||
SVGA_NEW_RAST |
|
||||
SVGA_NEW_FRAME_BUFFER |
|
||||
SVGA_NEW_NEED_PIPELINE |
|
||||
SVGA_NEW_FS |
|
||||
SVGA_NEW_REDUCED_PRIMITIVE),
|
||||
|
||||
emit_rss
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue