summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/r600/r600_hw_context.c2
-rw-r--r--src/gallium/drivers/r600/r600_pipe.h8
-rw-r--r--src/gallium/drivers/r600/r600_state_common.c37
3 files changed, 33 insertions, 14 deletions
diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c
index 4663d99c0b6..4511ce0c01e 100644
--- a/src/gallium/drivers/r600/r600_hw_context.c
+++ b/src/gallium/drivers/r600/r600_hw_context.c
@@ -369,6 +369,8 @@ void r600_begin_new_cs(struct r600_context *ctx)
/* Re-emit the draw state. */
ctx->last_primitive_type = -1;
ctx->last_start_instance = -1;
+ ctx->last_rast_prim = -1;
+ ctx->current_rast_prim = -1;
assert(!ctx->b.gfx.cs->prev_dw);
ctx->b.initial_gfx_cs_size = ctx->b.gfx.cs->current.cdw;
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index a05d543f0d1..86634b8681f 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -322,9 +322,9 @@ struct r600_pipe_shader_selector {
enum pipe_shader_type type;
/* geometry shader properties */
- unsigned gs_output_prim;
- unsigned gs_max_out_vertices;
- unsigned gs_num_invocations;
+ enum pipe_prim_type gs_output_prim;
+ unsigned gs_max_out_vertices;
+ unsigned gs_num_invocations;
/* TCS/VS */
uint64_t lds_patch_outputs_written_mask;
@@ -512,6 +512,8 @@ struct r600_context {
/* Last draw state (-1 = unset). */
enum pipe_prim_type last_primitive_type; /* Last primitive type used in draw_vbo. */
+ enum pipe_prim_type current_rast_prim; /* primitive type after TES, GS */
+ enum pipe_prim_type last_rast_prim;
unsigned last_start_instance;
void *sb_context;
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index d1251469079..e4d16609339 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -1666,6 +1666,27 @@ void r600_emit_clip_misc_state(struct r600_context *rctx, struct r600_atom *atom
S_028AB4_REUSE_OFF(state->vs_out_viewport));
}
+/* rast_prim is the primitive type after GS. */
+static inline void r600_emit_rasterizer_prim_state(struct r600_context *rctx)
+{
+ struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
+ unsigned ls_mask = 0;
+ enum pipe_prim_type rast_prim = rctx->current_rast_prim;
+ if (rast_prim == rctx->last_rast_prim)
+ return;
+
+ if (rast_prim == PIPE_PRIM_LINES)
+ ls_mask = 1;
+ else if (rast_prim == PIPE_PRIM_LINE_STRIP ||
+ rast_prim == PIPE_PRIM_LINE_LOOP)
+ ls_mask = 2;
+
+ radeon_set_context_reg(cs, R_028A0C_PA_SC_LINE_STIPPLE,
+ S_028A0C_AUTO_RESET_CNTL(ls_mask) |
+ (rctx->rasterizer ? rctx->rasterizer->pa_sc_line_stipple : 0));
+ rctx->last_rast_prim = rast_prim;
+}
+
static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
{
struct r600_context *rctx = (struct r600_context *)ctx;
@@ -1704,6 +1725,10 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
return;
}
+ rctx->current_rast_prim = (rctx->gs_shader)? rctx->gs_shader->gs_output_prim
+ : (rctx->tes_shader)? rctx->tes_shader->info.properties[TGSI_PROPERTY_TES_PRIM_MODE]
+ : info->mode;
+
if (info->indexed) {
/* Initialize the index buffer struct. */
pipe_resource_reference(&ib.buffer, rctx->index_buffer.buffer);
@@ -1863,17 +1888,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
/* Update the primitive type. */
if (rctx->last_primitive_type != info->mode) {
- unsigned ls_mask = 0;
-
- if (info->mode == PIPE_PRIM_LINES)
- ls_mask = 1;
- else if (info->mode == PIPE_PRIM_LINE_STRIP ||
- info->mode == PIPE_PRIM_LINE_LOOP)
- ls_mask = 2;
-
- radeon_set_context_reg(cs, R_028A0C_PA_SC_LINE_STIPPLE,
- S_028A0C_AUTO_RESET_CNTL(ls_mask) |
- (rctx->rasterizer ? rctx->rasterizer->pa_sc_line_stipple : 0));
+ r600_emit_rasterizer_prim_state(rctx);
radeon_set_config_reg(cs, R_008958_VGT_PRIMITIVE_TYPE,
r600_conv_pipe_prim(info->mode));