summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2016-08-26 17:26:43 +0200
committerMarek Olšák <[email protected]>2016-09-05 18:01:15 +0200
commit687c4be9cf61df18e5318f918a32e24d0a2aca0e (patch)
tree0525c6c597eda19cd94f9bcafdde6c0a58ce3949 /src/gallium/drivers
parent8b0507672e65c93307b39255186ed6651e8dde04 (diff)
gallium/radeon: set VPORT_ZMIN/MAX registers correctly
Calculate depth ranges from viewport states and pipe_rasterizer_state::clip_halfz. The evergreend.h change is required to silence a warning. This fixes this recently updated piglit: arb_depth_clamp/depth-clamp-range Reviewed-by: Bas Nieuwenhuizen <[email protected]> Reviewed-by: Nicolai Hähnle <[email protected]>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/r600/evergreen_state.c1
-rw-r--r--src/gallium/drivers/r600/evergreend.h4
-rw-r--r--src/gallium/drivers/r600/r600_hw_context.c1
-rw-r--r--src/gallium/drivers/r600/r600_pipe.h1
-rw-r--r--src/gallium/drivers/r600/r600_state.c1
-rw-r--r--src/gallium/drivers/r600/r600_state_common.c2
-rw-r--r--src/gallium/drivers/radeon/r600_pipe_common.h5
-rw-r--r--src/gallium/drivers/radeon/r600_viewport.c73
-rw-r--r--src/gallium/drivers/radeon/r600d_common.h2
-rw-r--r--src/gallium/drivers/radeonsi/si_hw_context.c1
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c3
-rw-r--r--src/gallium/drivers/radeonsi/si_state.h1
12 files changed, 82 insertions, 13 deletions
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 11c8161672e..5ca5453a8d7 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -473,6 +473,7 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx,
r600_init_command_buffer(&rs->buffer, 30);
rs->scissor_enable = state->scissor;
+ rs->clip_halfz = state->clip_halfz;
rs->flatshade = state->flatshade;
rs->sprite_coord_enable = state->sprite_coord_enable;
rs->two_side = state->light_twoside;
diff --git a/src/gallium/drivers/r600/evergreend.h b/src/gallium/drivers/r600/evergreend.h
index a81b6c5fc81..40ba7c15392 100644
--- a/src/gallium/drivers/r600/evergreend.h
+++ b/src/gallium/drivers/r600/evergreend.h
@@ -1863,8 +1863,8 @@
#define R_0283F8_SQ_VTX_SEMANTIC_30 0x000283F8
#define R_0283FC_SQ_VTX_SEMANTIC_31 0x000283FC
#define R_0288F0_SQ_VTX_SEMANTIC_CLEAR 0x000288F0
-#define R_0282D0_PA_SC_VPORT_ZMIN_0 0x000282D0
-#define R_0282D4_PA_SC_VPORT_ZMAX_0 0x000282D4
+#define R_0282D0_PA_SC_VPORT_ZMIN_0 0x0282D0
+#define R_0282D4_PA_SC_VPORT_ZMAX_0 0x0282D4
#define R_028400_VGT_MAX_VTX_INDX 0x00028400
#define R_028404_VGT_MIN_VTX_INDX 0x00028404
#define R_028408_VGT_INDX_OFFSET 0x00028408
diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c
index 58ba09d1014..dc5ad7537b9 100644
--- a/src/gallium/drivers/r600/r600_hw_context.c
+++ b/src/gallium/drivers/r600/r600_hw_context.c
@@ -312,6 +312,7 @@ void r600_begin_new_cs(struct r600_context *ctx)
ctx->b.scissors.dirty_mask = (1 << R600_MAX_VIEWPORTS) - 1;
r600_mark_atom_dirty(ctx, &ctx->b.scissors.atom);
ctx->b.viewports.dirty_mask = (1 << R600_MAX_VIEWPORTS) - 1;
+ ctx->b.viewports.depth_range_dirty_mask = (1 << R600_MAX_VIEWPORTS) - 1;
r600_mark_atom_dirty(ctx, &ctx->b.viewports.atom);
if (ctx->b.chip_class <= EVERGREEN) {
r600_mark_atom_dirty(ctx, &ctx->config_state.atom);
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index e1b2aeddf01..4403aca687a 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -276,6 +276,7 @@ struct r600_rasterizer_state {
bool offset_units_unscaled;
bool scissor_enable;
bool multisample_enable;
+ bool clip_halfz;
};
struct r600_poly_offset_state {
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index fb2861a2359..c8768e0343a 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -472,6 +472,7 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
r600_init_command_buffer(&rs->buffer, 30);
rs->scissor_enable = state->scissor;
+ rs->clip_halfz = state->clip_halfz;
rs->flatshade = state->flatshade;
rs->sprite_coord_enable = state->sprite_coord_enable;
rs->two_side = state->light_twoside;
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index 6f8053a069d..bb994297c11 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -366,7 +366,7 @@ static void r600_bind_rs_state(struct pipe_context *ctx, void *state)
r600_mark_atom_dirty(rctx, &rctx->clip_misc_state.atom);
}
- r600_set_scissor_enable(&rctx->b, rs->scissor_enable);
+ r600_viewport_set_rast_deps(&rctx->b, rs->scissor_enable, rs->clip_halfz);
/* Re-emit PA_SC_LINE_STIPPLE. */
rctx->last_primitive_type = -1;
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index d821eaa6318..aa40a54f43d 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -486,6 +486,7 @@ struct r600_scissors {
struct r600_viewports {
struct r600_atom atom;
unsigned dirty_mask;
+ unsigned depth_range_dirty_mask;
struct pipe_viewport_state states[R600_MAX_VIEWPORTS];
struct r600_signed_scissor as_scissor[R600_MAX_VIEWPORTS];
};
@@ -537,6 +538,7 @@ struct r600_common_context {
struct r600_scissors scissors;
struct r600_viewports viewports;
bool scissor_enabled;
+ bool clip_halfz;
bool vs_writes_viewport_index;
bool vs_disables_clipping_viewport;
@@ -793,7 +795,8 @@ void r600_init_context_texture_functions(struct r600_common_context *rctx);
/* r600_viewport.c */
void evergreen_apply_scissor_bug_workaround(struct r600_common_context *rctx,
struct pipe_scissor_state *scissor);
-void r600_set_scissor_enable(struct r600_common_context *rctx, bool enable);
+void r600_viewport_set_rast_deps(struct r600_common_context *rctx,
+ bool scissor_enable, bool clip_halfz);
void r600_update_vs_writes_viewport_index(struct r600_common_context *rctx,
struct tgsi_shader_info *info);
void r600_init_viewport_functions(struct r600_common_context *rctx);
diff --git a/src/gallium/drivers/radeon/r600_viewport.c b/src/gallium/drivers/radeon/r600_viewport.c
index 2d6878391da..2de13820545 100644
--- a/src/gallium/drivers/radeon/r600_viewport.c
+++ b/src/gallium/drivers/radeon/r600_viewport.c
@@ -22,6 +22,7 @@
*/
#include "r600_cs.h"
+#include "util/u_viewport.h"
#include "tgsi/tgsi_scan.h"
#define GET_MAX_SCISSOR(rctx) (rctx->chip_class >= EVERGREEN ? 16384 : 8192)
@@ -260,6 +261,7 @@ static void r600_set_viewport_states(struct pipe_context *ctx,
const struct pipe_viewport_state *state)
{
struct r600_common_context *rctx = (struct r600_common_context *)ctx;
+ unsigned mask;
int i;
for (i = 0; i < num_viewports; i++) {
@@ -270,8 +272,10 @@ static void r600_set_viewport_states(struct pipe_context *ctx,
&rctx->viewports.as_scissor[index]);
}
- rctx->viewports.dirty_mask |= ((1 << num_viewports) - 1) << start_slot;
- rctx->scissors.dirty_mask |= ((1 << num_viewports) - 1) << start_slot;
+ mask = ((1 << num_viewports) - 1) << start_slot;
+ rctx->viewports.dirty_mask |= mask;
+ rctx->viewports.depth_range_dirty_mask |= mask;
+ rctx->scissors.dirty_mask |= mask;
rctx->set_atom_dirty(rctx, &rctx->viewports.atom, true);
rctx->set_atom_dirty(rctx, &rctx->scissors.atom, true);
}
@@ -289,7 +293,7 @@ static void r600_emit_one_viewport(struct r600_common_context *rctx,
radeon_emit(cs, fui(state->translate[2]));
}
-static void r600_emit_viewports(struct r600_common_context *rctx, struct r600_atom *atom)
+static void r600_emit_viewports(struct r600_common_context *rctx)
{
struct radeon_winsys_cs *cs = rctx->gfx.cs;
struct pipe_viewport_state *states = rctx->viewports.states;
@@ -319,13 +323,64 @@ static void r600_emit_viewports(struct r600_common_context *rctx, struct r600_at
rctx->viewports.dirty_mask = 0;
}
-void r600_set_scissor_enable(struct r600_common_context *rctx, bool enable)
+static void r600_emit_depth_ranges(struct r600_common_context *rctx)
{
- if (rctx->scissor_enabled != enable) {
- rctx->scissor_enabled = enable;
+ struct radeon_winsys_cs *cs = rctx->gfx.cs;
+ struct pipe_viewport_state *states = rctx->viewports.states;
+ unsigned mask = rctx->viewports.depth_range_dirty_mask;
+ float zmin, zmax;
+
+ /* The simple case: Only 1 viewport is active. */
+ if (!rctx->vs_writes_viewport_index) {
+ if (!(mask & 1))
+ return;
+
+ util_viewport_zmin_zmax(&states[0], rctx->clip_halfz, &zmin, &zmax);
+
+ radeon_set_context_reg_seq(cs, R_0282D0_PA_SC_VPORT_ZMIN_0, 2);
+ radeon_emit(cs, fui(zmin));
+ radeon_emit(cs, fui(zmax));
+ rctx->viewports.depth_range_dirty_mask &= ~1; /* clear one bit */
+ return;
+ }
+
+ while (mask) {
+ int start, count, i;
+
+ u_bit_scan_consecutive_range(&mask, &start, &count);
+
+ radeon_set_context_reg_seq(cs, R_0282D0_PA_SC_VPORT_ZMIN_0 +
+ start * 4 * 2, count * 2);
+ for (i = start; i < start+count; i++) {
+ util_viewport_zmin_zmax(&states[i], rctx->clip_halfz, &zmin, &zmax);
+ radeon_emit(cs, fui(zmin));
+ radeon_emit(cs, fui(zmax));
+ }
+ }
+ rctx->viewports.depth_range_dirty_mask = 0;
+}
+
+static void r600_emit_viewport_states(struct r600_common_context *rctx,
+ struct r600_atom *atom)
+{
+ r600_emit_viewports(rctx);
+ r600_emit_depth_ranges(rctx);
+}
+
+/* Set viewport dependencies on pipe_rasterizer_state. */
+void r600_viewport_set_rast_deps(struct r600_common_context *rctx,
+ bool scissor_enable, bool clip_halfz)
+{
+ if (rctx->scissor_enabled != scissor_enable) {
+ rctx->scissor_enabled = scissor_enable;
rctx->scissors.dirty_mask = (1 << R600_MAX_VIEWPORTS) - 1;
rctx->set_atom_dirty(rctx, &rctx->scissors.atom, true);
}
+ if (rctx->clip_halfz != clip_halfz) {
+ rctx->clip_halfz = clip_halfz;
+ rctx->viewports.depth_range_dirty_mask = (1 << R600_MAX_VIEWPORTS) - 1;
+ rctx->set_atom_dirty(rctx, &rctx->viewports.atom, true);
+ }
}
/**
@@ -359,14 +414,16 @@ void r600_update_vs_writes_viewport_index(struct r600_common_context *rctx,
if (rctx->scissors.dirty_mask)
rctx->set_atom_dirty(rctx, &rctx->scissors.atom, true);
- if (rctx->viewports.dirty_mask)
+
+ if (rctx->viewports.dirty_mask ||
+ rctx->viewports.depth_range_dirty_mask)
rctx->set_atom_dirty(rctx, &rctx->viewports.atom, true);
}
void r600_init_viewport_functions(struct r600_common_context *rctx)
{
rctx->scissors.atom.emit = r600_emit_scissors;
- rctx->viewports.atom.emit = r600_emit_viewports;
+ rctx->viewports.atom.emit = r600_emit_viewport_states;
rctx->scissors.atom.num_dw = (2 + 16 * 2) + 6;
rctx->viewports.atom.num_dw = 2 + 16 * 6;
diff --git a/src/gallium/drivers/radeon/r600d_common.h b/src/gallium/drivers/radeon/r600d_common.h
index 6f534b3e5cd..3dbe43a8b56 100644
--- a/src/gallium/drivers/radeon/r600d_common.h
+++ b/src/gallium/drivers/radeon/r600d_common.h
@@ -246,5 +246,7 @@
#define S_028254_BR_Y(x) (((unsigned)(x) & 0x7FFF) << 16)
#define G_028254_BR_Y(x) (((x) >> 16) & 0x7FFF)
#define C_028254_BR_Y 0x8000FFFF
+#define R_0282D0_PA_SC_VPORT_ZMIN_0 0x0282D0
+#define R_0282D4_PA_SC_VPORT_ZMAX_0 0x0282D4
#endif
diff --git a/src/gallium/drivers/radeonsi/si_hw_context.c b/src/gallium/drivers/radeonsi/si_hw_context.c
index aeccb2d85f2..a03b3275d04 100644
--- a/src/gallium/drivers/radeonsi/si_hw_context.c
+++ b/src/gallium/drivers/radeonsi/si_hw_context.c
@@ -213,6 +213,7 @@ void si_begin_new_cs(struct si_context *ctx)
ctx->b.scissors.dirty_mask = (1 << R600_MAX_VIEWPORTS) - 1;
ctx->b.viewports.dirty_mask = (1 << R600_MAX_VIEWPORTS) - 1;
+ ctx->b.viewports.depth_range_dirty_mask = (1 << R600_MAX_VIEWPORTS) - 1;
si_mark_atom_dirty(ctx, &ctx->b.scissors.atom);
si_mark_atom_dirty(ctx, &ctx->b.viewports.atom);
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index f54b0bcc3a8..60ba3f6e8b3 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -733,6 +733,7 @@ static void *si_create_rs_state(struct pipe_context *ctx,
}
rs->scissor_enable = state->scissor;
+ rs->clip_halfz = state->clip_halfz;
rs->two_side = state->light_twoside;
rs->multisample_enable = state->multisample;
rs->force_persample_interp = state->force_persample_interp;
@@ -872,7 +873,7 @@ static void si_bind_rs_state(struct pipe_context *ctx, void *state)
si_mark_atom_dirty(sctx, &sctx->msaa_sample_locs.atom);
}
- r600_set_scissor_enable(&sctx->b, rs->scissor_enable);
+ r600_viewport_set_rast_deps(&sctx->b, rs->scissor_enable, rs->clip_halfz);
si_pm4_bind_state(sctx, rasterizer, rs);
si_update_poly_offset_state(sctx);
diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
index f4f75758dbf..d0e519c4994 100644
--- a/src/gallium/drivers/radeonsi/si_state.h
+++ b/src/gallium/drivers/radeonsi/si_state.h
@@ -76,6 +76,7 @@ struct si_state_rasterizer {
bool clamp_fragment_color;
bool rasterizer_discard;
bool scissor_enable;
+ bool clip_halfz;
};
struct si_dsa_stencil_ref_part {