radeonsi: precompute NGG cull flags in si_create_rs_state
authorMarek Olšák <marek.olsak@amd.com>
Thu, 14 Jan 2021 12:43:19 +0000 (07:43 -0500)
committerMarek Olšák <marek.olsak@amd.com>
Sat, 30 Jan 2021 20:41:23 +0000 (15:41 -0500)
Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8794>

src/gallium/drivers/radeonsi/si_state.c
src/gallium/drivers/radeonsi/si_state.h
src/gallium/drivers/radeonsi/si_state_draw.cpp

index 8b0ed04..57b3c94 100644 (file)
@@ -881,6 +881,30 @@ static void *si_create_rs_state(struct pipe_context *ctx, const struct pipe_rast
                          S_028810_DX_RASTERIZATION_KILL(state->rasterizer_discard) |
                          S_028810_DX_LINEAR_ATTR_CLIP_ENA(1);
 
+   if (rs->rasterizer_discard) {
+      rs->ngg_cull_flags = SI_NGG_CULL_FRONT_FACE | SI_NGG_CULL_BACK_FACE;
+      rs->ngg_cull_flags_y_inverted = rs->ngg_cull_flags;
+   } else {
+      /* Polygon mode can't use view and small primitive culling,
+       * because it draws points or lines where the culling depends
+       * on the point or line width.
+       */
+      if (!rs->polygon_mode_enabled) {
+         rs->ngg_cull_flags |= SI_NGG_CULL_VIEW_SMALLPRIMS;
+         rs->ngg_cull_flags_y_inverted |= SI_NGG_CULL_VIEW_SMALLPRIMS;
+      }
+
+      if (rs->cull_front) {
+         rs->ngg_cull_flags |= SI_NGG_CULL_FRONT_FACE;
+         rs->ngg_cull_flags_y_inverted |= SI_NGG_CULL_BACK_FACE;
+      }
+
+      if (rs->cull_back) {
+         rs->ngg_cull_flags |= SI_NGG_CULL_BACK_FACE;
+         rs->ngg_cull_flags_y_inverted |= SI_NGG_CULL_FRONT_FACE;
+      }
+   }
+
    si_pm4_set_reg(
       pm4, R_0286D4_SPI_INTERP_CONTROL_0,
       S_0286D4_FLAT_SHADE_ENA(1) | S_0286D4_PNT_SPRITE_ENA(state->point_quad_rasterization) |
index 68e9739..44ee44c 100644 (file)
@@ -75,6 +75,8 @@ struct si_state_rasterizer {
    unsigned pa_cl_clip_cntl;
    float line_width;
    float max_point_size;
+   unsigned ngg_cull_flags : 8;
+   unsigned ngg_cull_flags_y_inverted : 8;
    unsigned sprite_coord_enable : 8;
    unsigned clip_plane_enable : 8;
    unsigned half_pixel_center : 1;
index 2bb7035..33d5496 100644 (file)
@@ -1985,23 +1985,8 @@ static void si_draw_vbo(struct pipe_context *ctx,
             total_direct_count > hw_vs->ngg_cull_nonindexed_fast_launch_vert_threshold &&
             prim & ((1 << PIPE_PRIM_TRIANGLES) |
                     (1 << PIPE_PRIM_TRIANGLE_STRIP))))) {
-         uint8_t ngg_culling = 0;
-
-         if (rs->rasterizer_discard) {
-            ngg_culling |= SI_NGG_CULL_FRONT_FACE | SI_NGG_CULL_BACK_FACE;
-         } else {
-            /* Polygon mode can't use view and small primitive culling,
-             * because it draws points or lines where the culling depends
-             * on the point or line width.
-             */
-            if (!rs->polygon_mode_enabled)
-               ngg_culling |= SI_NGG_CULL_VIEW_SMALLPRIMS;
-
-            if (sctx->viewport0_y_inverted ? rs->cull_back : rs->cull_front)
-               ngg_culling |= SI_NGG_CULL_FRONT_FACE;
-            if (sctx->viewport0_y_inverted ? rs->cull_front : rs->cull_back)
-               ngg_culling |= SI_NGG_CULL_BACK_FACE;
-         }
+         uint8_t ngg_culling = sctx->viewport0_y_inverted ? rs->ngg_cull_flags_y_inverted :
+                                                            rs->ngg_cull_flags;
 
          /* Use NGG fast launch for certain primitive types.
           * A draw must have at least 1 full primitive.