summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2018-05-30 22:38:05 -0400
committerMarek Olšák <[email protected]>2018-06-13 22:00:31 -0400
commitd6974feb90e7c813a0ceb93fa77812a0197ffe31 (patch)
tree74317d8979738f36e879c087530abd2c594d1f26 /src
parent68b1c669e7291fc3e5629b1f44cdd97f92db702a (diff)
radeonsi: move the guardband registers into a separate state atom
They have a different frequency of updates and don't change when scissors change. I think this even fixes something in si_update_vs_viewport_state. Tested-by: Dieter Nützel <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/radeonsi/si_gfx_cs.c1
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c9
-rw-r--r--src/gallium/drivers/radeonsi/si_state.h2
-rw-r--r--src/gallium/drivers/radeonsi/si_state_draw.c6
-rw-r--r--src/gallium/drivers/radeonsi/si_state_viewport.c36
5 files changed, 35 insertions, 19 deletions
diff --git a/src/gallium/drivers/radeonsi/si_gfx_cs.c b/src/gallium/drivers/radeonsi/si_gfx_cs.c
index b81773e01a0..e01705d0775 100644
--- a/src/gallium/drivers/radeonsi/si_gfx_cs.c
+++ b/src/gallium/drivers/radeonsi/si_gfx_cs.c
@@ -284,6 +284,7 @@ void si_begin_new_gfx_cs(struct si_context *ctx)
ctx->scissors.dirty_mask = (1 << SI_MAX_VIEWPORTS) - 1;
ctx->viewports.dirty_mask = (1 << SI_MAX_VIEWPORTS) - 1;
ctx->viewports.depth_range_dirty_mask = (1 << SI_MAX_VIEWPORTS) - 1;
+ si_mark_atom_dirty(ctx, &ctx->atoms.s.guardband);
si_mark_atom_dirty(ctx, &ctx->atoms.s.scissors);
si_mark_atom_dirty(ctx, &ctx->atoms.s.viewports);
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index c87f79e0190..69a53f7a10b 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -1007,14 +1007,17 @@ static void si_bind_rs_state(struct pipe_context *ctx, void *state)
si_update_poly_offset_state(sctx);
if (!old_rs ||
- (old_rs->scissor_enable != rs->scissor_enable ||
- old_rs->line_width != rs->line_width ||
- old_rs->max_point_size != rs->max_point_size)) {
+ old_rs->scissor_enable != rs->scissor_enable) {
sctx->scissors.dirty_mask = (1 << SI_MAX_VIEWPORTS) - 1;
si_mark_atom_dirty(sctx, &sctx->atoms.s.scissors);
}
if (!old_rs ||
+ old_rs->line_width != rs->line_width ||
+ old_rs->max_point_size != rs->max_point_size)
+ si_mark_atom_dirty(sctx, &sctx->atoms.s.guardband);
+
+ if (!old_rs ||
old_rs->clip_halfz != rs->clip_halfz) {
sctx->viewports.depth_range_dirty_mask = (1 << SI_MAX_VIEWPORTS) - 1;
si_mark_atom_dirty(sctx, &sctx->atoms.s.viewports);
diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
index dc05021f492..5b9d7402019 100644
--- a/src/gallium/drivers/radeonsi/si_state.h
+++ b/src/gallium/drivers/radeonsi/si_state.h
@@ -207,6 +207,7 @@ union si_state_atoms {
struct si_atom clip_regs;
struct si_atom clip_state;
struct si_atom shader_pointers;
+ struct si_atom guardband;
struct si_atom scissors;
struct si_atom viewports;
struct si_atom stencil_ref;
@@ -234,6 +235,7 @@ static inline unsigned si_atoms_that_roll_context(void)
SI_ATOM_BIT(blend_color) |
SI_ATOM_BIT(clip_regs) |
SI_ATOM_BIT(clip_state) |
+ SI_ATOM_BIT(guardband) |
SI_ATOM_BIT(scissors) |
SI_ATOM_BIT(viewports) |
SI_ATOM_BIT(stencil_ref) |
diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c
index 5588c9a2c53..e33e235620a 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -1277,10 +1277,8 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
if (rast_prim != sctx->current_rast_prim) {
bool old_is_poly = sctx->current_rast_prim >= PIPE_PRIM_TRIANGLES;
bool new_is_poly = rast_prim >= PIPE_PRIM_TRIANGLES;
- if (old_is_poly != new_is_poly) {
- sctx->scissors.dirty_mask = (1 << SI_MAX_VIEWPORTS) - 1;
- si_mark_atom_dirty(sctx, &sctx->atoms.s.scissors);
- }
+ if (old_is_poly != new_is_poly)
+ si_mark_atom_dirty(sctx, &sctx->atoms.s.guardband);
sctx->current_rast_prim = rast_prim;
sctx->do_update_shaders = true;
diff --git a/src/gallium/drivers/radeonsi/si_state_viewport.c b/src/gallium/drivers/radeonsi/si_state_viewport.c
index bffb1f91827..97b1b89b48b 100644
--- a/src/gallium/drivers/radeonsi/si_state_viewport.c
+++ b/src/gallium/drivers/radeonsi/si_state_viewport.c
@@ -136,14 +136,28 @@ static void si_emit_one_scissor(struct si_context *ctx,
/* the range is [-MAX, MAX] */
#define SI_MAX_VIEWPORT_RANGE 32768
-static void si_emit_guardband(struct si_context *ctx,
- struct si_signed_scissor *vp_as_scissor)
+static void si_emit_guardband(struct si_context *ctx)
{
+ const struct si_signed_scissor *vp_as_scissor;
+ struct si_signed_scissor max_vp_scissor;
struct radeon_winsys_cs *cs = ctx->gfx_cs;
struct pipe_viewport_state vp;
float left, top, right, bottom, max_range, guardband_x, guardband_y;
float discard_x, discard_y;
+ if (ctx->vs_writes_viewport_index) {
+ /* Shaders can draw to any viewport. Make a union of all
+ * viewports. */
+ max_vp_scissor = ctx->viewports.as_scissor[0];
+ for (unsigned i = 1; i < SI_MAX_VIEWPORTS; i++) {
+ si_scissor_make_union(&max_vp_scissor,
+ &ctx->viewports.as_scissor[i]);
+ }
+ vp_as_scissor = &max_vp_scissor;
+ } else {
+ vp_as_scissor = &ctx->viewports.as_scissor[0];
+ }
+
/* Reconstruct the viewport transformation from the scissor. */
vp.translate[0] = (vp_as_scissor->minx + vp_as_scissor->maxx) / 2.0;
vp.translate[1] = (vp_as_scissor->miny + vp_as_scissor->maxy) / 2.0;
@@ -216,8 +230,6 @@ static void si_emit_scissors(struct si_context *ctx)
struct pipe_scissor_state *states = ctx->scissors.states;
unsigned mask = ctx->scissors.dirty_mask;
bool scissor_enabled = false;
- struct si_signed_scissor max_vp_scissor;
- int i;
if (ctx->queued.named.rasterizer)
scissor_enabled = ctx->queued.named.rasterizer->scissor_enable;
@@ -231,17 +243,10 @@ static void si_emit_scissors(struct si_context *ctx)
radeon_set_context_reg_seq(cs, R_028250_PA_SC_VPORT_SCISSOR_0_TL, 2);
si_emit_one_scissor(ctx, cs, vp, scissor_enabled ? &states[0] : NULL);
- si_emit_guardband(ctx, vp);
ctx->scissors.dirty_mask &= ~1; /* clear one bit */
return;
}
- /* Shaders can draw to any viewport. Make a union of all viewports. */
- max_vp_scissor = ctx->viewports.as_scissor[0];
- for (i = 1; i < SI_MAX_VIEWPORTS; i++)
- si_scissor_make_union(&max_vp_scissor,
- &ctx->viewports.as_scissor[i]);
-
while (mask) {
int start, count, i;
@@ -254,7 +259,6 @@ static void si_emit_scissors(struct si_context *ctx)
scissor_enabled ? &states[i] : NULL);
}
}
- si_emit_guardband(ctx, &max_vp_scissor);
ctx->scissors.dirty_mask = 0;
}
@@ -280,6 +284,7 @@ static void si_set_viewport_states(struct pipe_context *pctx,
ctx->viewports.depth_range_dirty_mask |= mask;
ctx->scissors.dirty_mask |= mask;
si_mark_atom_dirty(ctx, &ctx->atoms.s.viewports);
+ si_mark_atom_dirty(ctx, &ctx->atoms.s.guardband);
si_mark_atom_dirty(ctx, &ctx->atoms.s.scissors);
}
@@ -419,7 +424,13 @@ void si_update_vs_viewport_state(struct si_context *ctx)
}
/* Viewport index handling. */
+ if (ctx->vs_writes_viewport_index == info->writes_viewport_index)
+ return;
+
+ /* This changes how the guardband is computed. */
ctx->vs_writes_viewport_index = info->writes_viewport_index;
+ si_mark_atom_dirty(ctx, &ctx->atoms.s.guardband);
+
if (!ctx->vs_writes_viewport_index)
return;
@@ -433,6 +444,7 @@ void si_update_vs_viewport_state(struct si_context *ctx)
void si_init_viewport_functions(struct si_context *ctx)
{
+ ctx->atoms.s.guardband.emit = si_emit_guardband;
ctx->atoms.s.scissors.emit = si_emit_scissors;
ctx->atoms.s.viewports.emit = si_emit_viewport_states;