summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/svga
diff options
context:
space:
mode:
authorCharmaine Lee <[email protected]>2017-04-04 12:47:49 -0600
committerBrian Paul <[email protected]>2017-04-07 13:46:43 -0600
commitb4c4ee076244d0518af98e0beca1c12942c4bc36 (patch)
treea0327146039bbd592ab502ce6291be85e82a9f98 /src/gallium/drivers/svga
parentfed72ff6cb85fa6044335cfc41d8492458f53750 (diff)
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 <[email protected]>
Diffstat (limited to 'src/gallium/drivers/svga')
-rw-r--r--src/gallium/drivers/svga/svga_context.c7
-rw-r--r--src/gallium/drivers/svga/svga_context.h6
-rw-r--r--src/gallium/drivers/svga/svga_pipe_draw.c14
-rw-r--r--src/gallium/drivers/svga/svga_pipe_rasterizer.c17
-rw-r--r--src/gallium/drivers/svga/svga_state_fs.c21
-rw-r--r--src/gallium/drivers/svga/svga_state_rss.c102
6 files changed, 128 insertions, 39 deletions
diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c
index ec86073ccc9..04466fb7dee 100644
--- a/src/gallium/drivers/svga/svga_context.c
+++ b/src/gallium/drivers/svga/svga_context.c
@@ -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;
diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index 40966e9b52e..2b95a787870 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -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:
diff --git a/src/gallium/drivers/svga/svga_pipe_draw.c b/src/gallium/drivers/svga/svga_pipe_draw.c
index 30524a0e3ec..eaf46811ff7 100644
--- a/src/gallium/drivers/svga/svga_pipe_draw.c
+++ b/src/gallium/drivers/svga/svga_pipe_draw.c
@@ -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,
diff --git a/src/gallium/drivers/svga/svga_pipe_rasterizer.c b/src/gallium/drivers/svga/svga_pipe_rasterizer.c
index 70d89f5cc63..35351fc6080 100644
--- a/src/gallium/drivers/svga/svga_pipe_rasterizer.c
+++ b/src/gallium/drivers/svga/svga_pipe_rasterizer.c
@@ -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;
diff --git a/src/gallium/drivers/svga/svga_state_fs.c b/src/gallium/drivers/svga/svga_state_fs.c
index 48987445025..07a3614d79d 100644
--- a/src/gallium/drivers/svga/svga_state_fs.c
+++ b/src/gallium/drivers/svga/svga_state_fs.c
@@ -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
diff --git a/src/gallium/drivers/svga/svga_state_rss.c b/src/gallium/drivers/svga/svga_state_rss.c
index e22268d5b8f..d04ef8d6dd9 100644
--- a/src/gallium/drivers/svga/svga_state_rss.c
+++ b/src/gallium/drivers/svga/svga_state_rss.c
@@ -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 rasterization is to be disabled, disable depth and stencil
+ * testing as well.
+ */
+ 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 {
+ 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 (dirty & (SVGA_NEW_REDUCED_PRIMITIVE | SVGA_NEW_RAST)) {
- const struct svga_rasterizer_state *rast;
+ 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 (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 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;
+ 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