summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2016-04-10 03:29:57 +0200
committerMarek Olšák <[email protected]>2016-04-12 14:29:49 +0200
commitcb21f8a97cdd5ae240aecdfa417b60b2c0dd6789 (patch)
tree49ba0d9e92e80e16c3896f0e9c84b7ad3ad00696 /src/gallium/drivers
parent5b6a0b7fc02c27c334cf932cfdfd7bedef5a5198 (diff)
radeonsi: compute scissor from viewport in set_viewport_states
and clamp it right before emitting. This is a prerequisite for computing the guard band. Reviewed-by: Edward O'Callaghan <[email protected]> Reviewed-by: Grigori Goronzy <[email protected]> Reviewed-by: Nicolai Hähnle <[email protected]>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/radeonsi/si_pipe.h8
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c70
2 files changed, 48 insertions, 30 deletions
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index f665c8160e0..b600b86e47c 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -179,10 +179,18 @@ struct si_scissors {
struct pipe_scissor_state states[SI_MAX_VIEWPORTS];
};
+struct si_signed_scissor {
+ int minx;
+ int miny;
+ int maxx;
+ int maxy;
+};
+
struct si_viewports {
struct r600_atom atom;
unsigned dirty_mask;
struct pipe_viewport_state states[SI_MAX_VIEWPORTS];
+ struct si_signed_scissor as_scissor[SI_MAX_VIEWPORTS];
};
/* A shader state consists of the shader selector, which is a constant state
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index d75565a5c24..fb7a07099a1 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -838,40 +838,44 @@ static void si_set_scissor_states(struct pipe_context *ctx,
si_mark_atom_dirty(sctx, &sctx->scissors.atom);
}
-static void si_get_scissor_from_viewport(struct pipe_viewport_state *vp,
- struct pipe_scissor_state *scissor)
+static void si_get_scissor_from_viewport(const struct pipe_viewport_state *vp,
+ struct si_signed_scissor *scissor)
{
- /* These must be signed, unlike pipe_scissor_state. */
- int minx, miny, maxx, maxy, tmp;
+ int tmp;
/* Convert (-1, -1) and (1, 1) from clip space into window space. */
- minx = -vp->scale[0] + vp->translate[0];
- miny = -vp->scale[1] + vp->translate[1];
- maxx = vp->scale[0] + vp->translate[0];
- maxy = vp->scale[1] + vp->translate[1];
+ scissor->minx = -vp->scale[0] + vp->translate[0];
+ scissor->miny = -vp->scale[1] + vp->translate[1];
+ scissor->maxx = vp->scale[0] + vp->translate[0];
+ scissor->maxy = vp->scale[1] + vp->translate[1];
/* r600_draw_rectangle sets this. Disable the scissor. */
- if (minx == -1 && miny == -1 && maxx == 1 && maxy == 1) {
- minx = miny = 0;
- maxx = maxy = 16384;
+ if (scissor->minx == -1 && scissor->miny == -1 &&
+ scissor->maxx == 1 && scissor->maxy == 1) {
+ scissor->minx = scissor->miny = 0;
+ scissor->maxx = scissor->maxy = 16384;
}
/* Handle inverted viewports. */
- if (minx > maxx) {
- tmp = minx;
- minx = maxx;
- maxx = tmp;
+ if (scissor->minx > scissor->maxx) {
+ tmp = scissor->minx;
+ scissor->minx = scissor->maxx;
+ scissor->maxx = tmp;
}
- if (miny > maxy) {
- tmp = miny;
- miny = maxy;
- maxy = tmp;
+ if (scissor->miny > scissor->maxy) {
+ tmp = scissor->miny;
+ scissor->miny = scissor->maxy;
+ scissor->maxy = tmp;
}
+}
- scissor->minx = CLAMP(minx, 0, 16384);
- scissor->miny = CLAMP(miny, 0, 16384);
- scissor->maxx = CLAMP(maxx, 0, 16384);
- scissor->maxy = CLAMP(maxy, 0, 16384);
+static void si_clamp_scissor(struct pipe_scissor_state *out,
+ struct si_signed_scissor *scissor)
+{
+ out->minx = CLAMP(scissor->minx, 0, 16384);
+ out->miny = CLAMP(scissor->miny, 0, 16384);
+ out->maxx = CLAMP(scissor->maxx, 0, 16384);
+ out->maxy = CLAMP(scissor->maxy, 0, 16384);
}
static void si_clip_scissor(struct pipe_scissor_state *out,
@@ -884,7 +888,7 @@ static void si_clip_scissor(struct pipe_scissor_state *out,
}
static void si_emit_one_scissor(struct radeon_winsys_cs *cs,
- struct pipe_viewport_state *vp,
+ struct si_signed_scissor *vp_scissor,
struct pipe_scissor_state *scissor)
{
struct pipe_scissor_state final;
@@ -892,7 +896,7 @@ static void si_emit_one_scissor(struct radeon_winsys_cs *cs,
/* Since the guard band disables clipping, we have to clip per-pixel
* using a scissor.
*/
- si_get_scissor_from_viewport(vp, &final);
+ si_clamp_scissor(&final, vp_scissor);
if (scissor)
si_clip_scissor(&final, scissor);
@@ -913,12 +917,13 @@ static void si_emit_scissors(struct si_context *sctx, struct r600_atom *atom)
/* The simple case: Only 1 viewport is active. */
if (!si_get_vs_info(sctx)->writes_viewport_index) {
+ struct si_signed_scissor *vp = &sctx->viewports.as_scissor[0];
+
if (!(mask & 1))
return;
radeon_set_context_reg_seq(cs, R_028250_PA_SC_VPORT_SCISSOR_0_TL, 2);
- si_emit_one_scissor(cs, &sctx->viewports.states[0],
- scissor_enable ? &states[0] : NULL);
+ si_emit_one_scissor(cs, vp, scissor_enable ? &states[0] : NULL);
sctx->scissors.dirty_mask &= ~1; /* clear one bit */
return;
}
@@ -931,7 +936,7 @@ static void si_emit_scissors(struct si_context *sctx, struct r600_atom *atom)
radeon_set_context_reg_seq(cs, R_028250_PA_SC_VPORT_SCISSOR_0_TL +
start * 4 * 2, count * 2);
for (i = start; i < start+count; i++) {
- si_emit_one_scissor(cs, &sctx->viewports.states[i],
+ si_emit_one_scissor(cs, &sctx->viewports.as_scissor[i],
scissor_enable ? &states[i] : NULL);
}
}
@@ -946,8 +951,13 @@ static void si_set_viewport_states(struct pipe_context *ctx,
struct si_context *sctx = (struct si_context *)ctx;
int i;
- for (i = 0; i < num_viewports; i++)
- sctx->viewports.states[start_slot + i] = state[i];
+ for (i = 0; i < num_viewports; i++) {
+ unsigned index = start_slot + i;
+
+ sctx->viewports.states[index] = state[i];
+ si_get_scissor_from_viewport(&state[i],
+ &sctx->viewports.as_scissor[index]);
+ }
sctx->viewports.dirty_mask |= ((1 << num_viewports) - 1) << start_slot;
sctx->scissors.dirty_mask |= ((1 << num_viewports) - 1) << start_slot;