}
}
+ /* 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);
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;
svga->dirty = ~0;
svga->pred.query_id = SVGA3D_INVALID_ID;
+ svga->disable_rasterizer = FALSE;
return &svga->pipe;
/* used for rebinding */
unsigned default_constbuf_size[PIPE_SHADER_TYPES];
+
+ boolean rasterizer_discard; /* set if rasterization is disabled */
};
/** 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;
} pred;
boolean render_condition;
+ boolean disable_rasterizer; /* Set if to disable rasterization */
};
/* A flag for each state_tracker state object:
#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,
*/
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,
*/
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,
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;
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
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)
{
}
}
- 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;
}
SVGA_NEW_RAST |
SVGA_NEW_FRAME_BUFFER |
SVGA_NEW_NEED_PIPELINE |
+ SVGA_NEW_FS |
SVGA_NEW_REDUCED_PRIMITIVE),
emit_rss