gallium/radeon: set VPORT_ZMIN/MAX registers correctly
authorMarek Olšák <marek.olsak@amd.com>
Fri, 26 Aug 2016 15:26:43 +0000 (17:26 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Mon, 5 Sep 2016 16:01:15 +0000 (18:01 +0200)
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 <bas@basnieuwenhuizen.nl>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
12 files changed:
src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/evergreend.h
src/gallium/drivers/r600/r600_hw_context.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/r600/r600_state.c
src/gallium/drivers/r600/r600_state_common.c
src/gallium/drivers/radeon/r600_pipe_common.h
src/gallium/drivers/radeon/r600_viewport.c
src/gallium/drivers/radeon/r600d_common.h
src/gallium/drivers/radeonsi/si_hw_context.c
src/gallium/drivers/radeonsi/si_state.c
src/gallium/drivers/radeonsi/si_state.h

index 11c8161672ef0be8e1d900a63b74522edbb08b59..5ca5453a8d7547e3bb6484cfbdccf2c038d06555 100644 (file)
@@ -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;
index a81b6c5fc8153af15366cd9eb09cc31d860bf14c..40ba7c1539297b63c028cc1c5823c7f27acc2f31 100644 (file)
 #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
index 58ba09d1014a6503232a7085621569b9900806a9..dc5ad7537b999fe87e1c37eeb7eba2cd7bdf35da 100644 (file)
@@ -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);
index e1b2aeddf016c70c67e0defe8831fdf919a76c84..4403aca687a238f7c0efe3e0e52da35ae8d09992 100644 (file)
@@ -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 {
index fb2861a235958a4320bc42cb6c2467864de056ec..c8768e0343a9d2cf1e3bf165161fee55972737c6 100644 (file)
@@ -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;
index 6f8053a069d0f116dc5e17e9d1ba672c1a7e4492..bb994297c112712265278b32305042205fc57bed 100644 (file)
@@ -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;
index d821eaa63182c1f8c6830f81fdaf5487b801cee0..aa40a54f43dabd68516819394e023225b5ee182c 100644 (file)
@@ -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);
index 2d6878391da30fbd2ab2c1ee8a3bf2599db48c1c..2de13820545d3853b443acd1117f2344c516c01f 100644 (file)
@@ -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;
index 6f534b3e5cdeea48f00e6a5910d9cd427ece66cf..3dbe43a8b5663560e3c33a595ed443eb52e1e1b1 100644 (file)
 #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
index aeccb2d85f2d6a775960d103f4005427d402f321..a03b3275d047178e5587edaaab6d61ef96ddfcd8 100644 (file)
@@ -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);
 
index f54b0bcc3a87e848ae02934c4aeb6766830fea4f..60ba3f6e8b32cd141fa20858618b697ead73cb56 100644 (file)
@@ -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);
index f4f75758dbfc6106f62dc0d3a7fdd4919ddb52ff..d0e519c499477100bff0bd1560d50e0ad448ec84 100644 (file)
@@ -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 {