diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c index 08828ac8446..93fa67a953e 100644 --- a/src/gallium/drivers/radeonsi/si_blit.c +++ b/src/gallium/drivers/radeonsi/si_blit.c @@ -53,7 +53,7 @@ static void si_blitter_begin(struct pipe_context *ctx, enum si_blitter_op op) util_blitter_save_blend(sctx->blitter, sctx->queued.named.blend); util_blitter_save_depth_stencil_alpha(sctx->blitter, sctx->queued.named.dsa); - util_blitter_save_stencil_ref(sctx->blitter, &sctx->stencil_ref); + util_blitter_save_stencil_ref(sctx->blitter, &sctx->stencil_ref.state); util_blitter_save_rasterizer(sctx->blitter, sctx->queued.named.rasterizer); util_blitter_save_fragment_shader(sctx->blitter, sctx->ps_shader); util_blitter_save_geometry_shader(sctx->blitter, sctx->gs_shader); diff --git a/src/gallium/drivers/radeonsi/si_hw_context.c b/src/gallium/drivers/radeonsi/si_hw_context.c index 99aa039a0f4..fbac95d5b29 100644 --- a/src/gallium/drivers/radeonsi/si_hw_context.c +++ b/src/gallium/drivers/radeonsi/si_hw_context.c @@ -195,6 +195,7 @@ void si_begin_new_cs(struct si_context *ctx) si_mark_atom_dirty(ctx, &ctx->sample_mask.atom); si_mark_atom_dirty(ctx, &ctx->blend_color.atom); si_mark_atom_dirty(ctx, &ctx->db_render_state); + si_mark_atom_dirty(ctx, &ctx->stencil_ref.atom); si_mark_atom_dirty(ctx, &ctx->b.streamout.enable_atom); si_all_descriptors_begin_new_cs(ctx); diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 60124ea5cb5..6eb0cb3bc92 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -177,7 +177,6 @@ struct si_context { struct si_framebuffer framebuffer; struct si_vertex_element *vertex_elements; /* for saving when using blitter */ - struct pipe_stencil_ref stencil_ref; /* shaders */ struct si_shader_selector *ps_shader; struct si_shader_selector *gs_shader; @@ -198,6 +197,7 @@ struct si_context { unsigned border_color_offset; struct si_blend_color blend_color; + struct si_stencil_ref stencil_ref; struct si_scissors scissors; struct si_viewports viewports; struct si_clip_state clip_state; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index df1a13c6692..20e690b2bcf 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -825,39 +825,33 @@ static void si_delete_rs_state(struct pipe_context *ctx, void *state) /* * infeered state between dsa and stencil ref */ -static void si_update_dsa_stencil_ref(struct si_context *sctx) +static void si_emit_stencil_ref(struct si_context *sctx, struct r600_atom *atom) { - struct si_pm4_state *pm4; - struct pipe_stencil_ref *ref = &sctx->stencil_ref; - struct si_state_dsa *dsa = sctx->queued.named.dsa; + struct radeon_winsys_cs *cs = sctx->b.rings.gfx.cs; + struct pipe_stencil_ref *ref = &sctx->stencil_ref.state; + struct si_dsa_stencil_ref_part *dsa = &sctx->stencil_ref.dsa_part; - if (!dsa) - return; - - pm4 = CALLOC_STRUCT(si_pm4_state); - if (pm4 == NULL) - return; - - si_pm4_set_reg(pm4, R_028430_DB_STENCILREFMASK, - S_028430_STENCILTESTVAL(ref->ref_value[0]) | - S_028430_STENCILMASK(dsa->valuemask[0]) | - S_028430_STENCILWRITEMASK(dsa->writemask[0]) | - S_028430_STENCILOPVAL(1)); - si_pm4_set_reg(pm4, R_028434_DB_STENCILREFMASK_BF, - S_028434_STENCILTESTVAL_BF(ref->ref_value[1]) | - S_028434_STENCILMASK_BF(dsa->valuemask[1]) | - S_028434_STENCILWRITEMASK_BF(dsa->writemask[1]) | - S_028434_STENCILOPVAL_BF(1)); - - si_pm4_set_state(sctx, dsa_stencil_ref, pm4); + r600_write_context_reg_seq(cs, R_028430_DB_STENCILREFMASK, 2); + radeon_emit(cs, S_028430_STENCILTESTVAL(ref->ref_value[0]) | + S_028430_STENCILMASK(dsa->valuemask[0]) | + S_028430_STENCILWRITEMASK(dsa->writemask[0]) | + S_028430_STENCILOPVAL(1)); + radeon_emit(cs, S_028434_STENCILTESTVAL_BF(ref->ref_value[1]) | + S_028434_STENCILMASK_BF(dsa->valuemask[1]) | + S_028434_STENCILWRITEMASK_BF(dsa->writemask[1]) | + S_028434_STENCILOPVAL_BF(1)); } -static void si_set_pipe_stencil_ref(struct pipe_context *ctx, - const struct pipe_stencil_ref *state) +static void si_set_stencil_ref(struct pipe_context *ctx, + const struct pipe_stencil_ref *state) { struct si_context *sctx = (struct si_context *)ctx; - sctx->stencil_ref = *state; - si_update_dsa_stencil_ref(sctx); + + if (memcmp(&sctx->stencil_ref.state, state, sizeof(*state)) == 0) + return; + + sctx->stencil_ref.state = *state; + si_mark_atom_dirty(sctx, &sctx->stencil_ref.atom); } @@ -904,10 +898,10 @@ static void *si_create_dsa_state(struct pipe_context *ctx, return NULL; } - dsa->valuemask[0] = state->stencil[0].valuemask; - dsa->valuemask[1] = state->stencil[1].valuemask; - dsa->writemask[0] = state->stencil[0].writemask; - dsa->writemask[1] = state->stencil[1].writemask; + dsa->stencil_ref.valuemask[0] = state->stencil[0].valuemask; + dsa->stencil_ref.valuemask[1] = state->stencil[1].valuemask; + dsa->stencil_ref.writemask[0] = state->stencil[0].writemask; + dsa->stencil_ref.writemask[1] = state->stencil[1].writemask; db_depth_control = S_028800_Z_ENABLE(state->depth.enabled) | S_028800_Z_WRITE_ENABLE(state->depth.writemask) | @@ -960,7 +954,12 @@ static void si_bind_dsa_state(struct pipe_context *ctx, void *state) return; si_pm4_bind_state(sctx, dsa, dsa); - si_update_dsa_stencil_ref(sctx); + + if (memcmp(&dsa->stencil_ref, &sctx->stencil_ref.dsa_part, + sizeof(struct si_dsa_stencil_ref_part)) != 0) { + sctx->stencil_ref.dsa_part = dsa->stencil_ref; + si_mark_atom_dirty(sctx, &sctx->stencil_ref.atom); + } } static void si_delete_dsa_state(struct pipe_context *ctx, void *state) @@ -3069,6 +3068,7 @@ void si_init_state_functions(struct si_context *sctx) si_init_atom(sctx, &sctx->clip_state.atom, &sctx->atoms.s.clip_state, si_emit_clip_state, 2+6*4); si_init_atom(sctx, &sctx->scissors.atom, &sctx->atoms.s.scissors, si_emit_scissors, 16*4); si_init_atom(sctx, &sctx->viewports.atom, &sctx->atoms.s.viewports, si_emit_viewports, 16*8); + si_init_atom(sctx, &sctx->stencil_ref.atom, &sctx->atoms.s.stencil_ref, si_emit_stencil_ref, 4); sctx->b.b.create_blend_state = si_create_blend_state; sctx->b.b.bind_blend_state = si_bind_blend_state; @@ -3091,7 +3091,7 @@ void si_init_state_functions(struct si_context *sctx) sctx->b.b.set_clip_state = si_set_clip_state; sctx->b.b.set_scissor_states = si_set_scissor_states; sctx->b.b.set_viewport_states = si_set_viewport_states; - sctx->b.b.set_stencil_ref = si_set_pipe_stencil_ref; + sctx->b.b.set_stencil_ref = si_set_stencil_ref; sctx->b.b.set_framebuffer_state = si_set_framebuffer_state; sctx->b.b.get_sample_position = cayman_get_sample_position; diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index 68a7cf9c3b4..60483db19b5 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -60,13 +60,23 @@ struct si_state_rasterizer { bool poly_smooth; }; -struct si_state_dsa { - struct si_pm4_state pm4; - unsigned alpha_func; +struct si_dsa_stencil_ref_part { uint8_t valuemask[2]; uint8_t writemask[2]; }; +struct si_state_dsa { + struct si_pm4_state pm4; + unsigned alpha_func; + struct si_dsa_stencil_ref_part stencil_ref; +}; + +struct si_stencil_ref { + struct r600_atom atom; + struct pipe_stencil_ref state; + struct si_dsa_stencil_ref_part dsa_part; +}; + struct si_vertex_element { unsigned count; @@ -82,7 +92,6 @@ union si_state { struct si_state_dsa *dsa; struct si_pm4_state *fb_rs; struct si_pm4_state *fb_blend; - struct si_pm4_state *dsa_stencil_ref; struct si_pm4_state *ta_bordercolor_base; struct si_pm4_state *ls; struct si_pm4_state *hs; @@ -113,6 +122,7 @@ union si_state_atoms { struct r600_atom *shader_userdata; struct r600_atom *scissors; struct r600_atom *viewports; + struct r600_atom *stencil_ref; } s; struct r600_atom *array[0]; };