iris: Set XY Clipping correctly.
authorKenneth Graunke <kenneth@whitecape.org>
Mon, 29 Apr 2019 06:25:10 +0000 (23:25 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Mon, 29 Apr 2019 17:53:23 +0000 (10:53 -0700)
I was setting it based off a pipe_rasterizer_state field that appears
to be entirely dead outside of the draw module respecting it.

I should be setting it when the primitive type reaching the SF is
neither points nor lines.  This is, unfortunately, rather dirty,
as we have to look at the rasterizer state, the geometry shader state,
the tessellation evaluation shader state, and the primitive type...

src/gallium/drivers/iris/iris_context.h
src/gallium/drivers/iris/iris_draw.c
src/gallium/drivers/iris/iris_program.c
src/gallium/drivers/iris/iris_state.c

index 51bbdb681e72fa0ec9c80317ca2b77546d4d5333..31f345d36b082b5a8fa58bdd000b7dca21d67e24 100644 (file)
@@ -504,6 +504,9 @@ struct iris_context {
 
       unsigned urb_size;
 
+      /** Is a GS or TES outputting points or lines? */
+      bool output_topology_is_points_or_lines;
+
       /* Track last VS URB entry size */
       unsigned last_vs_entry_size;
 
@@ -548,6 +551,7 @@ struct iris_context {
       bool primitive_restart;
       unsigned cut_index;
       enum pipe_prim_type prim_mode:8;
+      bool prim_is_points_or_lines;
       uint8_t vertices_per_patch;
 
       /** The last compute grid size */
index 94af728c693f9106cafa486ba63914f423be862a..86fc95cac0c6b53bdada0af0abc73de61e2c8ea5 100644 (file)
 #include "util/u_transfer.h"
 #include "util/u_upload_mgr.h"
 #include "intel/compiler/brw_compiler.h"
+#include "intel/compiler/brw_eu_defines.h"
 #include "iris_context.h"
 #include "iris_defines.h"
 
+static bool
+prim_is_points_or_lines(const struct pipe_draw_info *draw)
+{
+   /* We don't need to worry about adjacency - it can only be used with
+    * geometry shaders, and we don't care about this info when GS is on.
+    */
+   return draw->mode == PIPE_PRIM_POINTS ||
+          draw->mode == PIPE_PRIM_LINES ||
+          draw->mode == PIPE_PRIM_LINE_LOOP ||
+          draw->mode == PIPE_PRIM_LINE_STRIP;
+}
+
 /**
  * Record the current primitive mode and restart information, flagging
  * related packets as dirty if necessary.
@@ -50,6 +63,14 @@ iris_update_draw_info(struct iris_context *ice,
    if (ice->state.prim_mode != info->mode) {
       ice->state.prim_mode = info->mode;
       ice->state.dirty |= IRIS_DIRTY_VF_TOPOLOGY;
+
+
+      /* For XY Clip enables */
+      bool points_or_lines = prim_is_points_or_lines(info);
+      if (points_or_lines != ice->state.prim_is_points_or_lines) {
+         ice->state.prim_is_points_or_lines = points_or_lines;
+         ice->state.dirty |= IRIS_DIRTY_CLIP;
+      }
    }
 
    if (info->mode == PIPE_PRIM_PATCHES &&
index eff7c77521256fda599a45f7b803a96f99fac031..30ec3f1ff86e9309bff17c86e50dd87db24b575d 100644 (file)
@@ -1241,6 +1241,33 @@ iris_update_compiled_shaders(struct iris_context *ice)
    if (dirty & IRIS_DIRTY_UNCOMPILED_GS)
       iris_update_compiled_gs(ice);
 
+   if (dirty & (IRIS_DIRTY_UNCOMPILED_GS | IRIS_DIRTY_UNCOMPILED_TES)) {
+      const struct iris_compiled_shader *gs =
+         ice->shaders.prog[MESA_SHADER_GEOMETRY];
+      const struct iris_compiled_shader *tes =
+         ice->shaders.prog[MESA_SHADER_TESS_EVAL];
+
+      bool points_or_lines = false;
+
+      if (gs) {
+         const struct brw_gs_prog_data *gs_prog_data = (void *) gs->prog_data;
+         points_or_lines =
+            gs_prog_data->output_topology == _3DPRIM_POINTLIST ||
+            gs_prog_data->output_topology == _3DPRIM_LINESTRIP;
+      } else if (tes) {
+         const struct brw_tes_prog_data *tes_data = (void *) tes->prog_data;
+         points_or_lines =
+            tes_data->output_topology == BRW_TESS_OUTPUT_TOPOLOGY_LINE ||
+            tes_data->output_topology == BRW_TESS_OUTPUT_TOPOLOGY_POINT;
+      }
+
+      if (ice->shaders.output_topology_is_points_or_lines != points_or_lines) {
+         /* Outbound to XY Clip enables */
+         ice->shaders.output_topology_is_points_or_lines = points_or_lines;
+         ice->state.dirty |= IRIS_DIRTY_CLIP;
+      }
+   }
+
    gl_shader_stage last_stage = last_vue_stage(ice);
    struct iris_compiled_shader *shader = ice->shaders.prog[last_stage];
    struct iris_uncompiled_shader *ish = ice->shaders.uncompiled[last_stage];
@@ -1261,7 +1288,6 @@ iris_update_compiled_shaders(struct iris_context *ice)
 
    if (dirty & IRIS_DIRTY_UNCOMPILED_FS)
       iris_update_compiled_fs(ice);
-   // ...
 
    /* Changing shader interfaces may require a URB configuration. */
    if (!(dirty & IRIS_DIRTY_URB)) {
index 479703f30fa7412d336e398590d878e6dbb63d8d..91659f4f67b0d840241bc74febe192850f0cf4a7 100644 (file)
@@ -1182,6 +1182,7 @@ struct iris_rasterizer_state {
    bool multisample;
    bool force_persample_interp;
    bool conservative_rasterization;
+   bool fill_mode_point_or_line;
    enum pipe_sprite_coord_mode sprite_coord_mode; /* PIPE_SPRITE_* */
    uint16_t sprite_coord_enable;
 };
@@ -1244,6 +1245,12 @@ iris_create_rasterizer_state(struct pipe_context *ctx,
    cso->conservative_rasterization =
       state->conservative_raster_mode == PIPE_CONSERVATIVE_RASTER_POST_SNAP;
 
+   cso->fill_mode_point_or_line =
+      state->fill_front == PIPE_POLYGON_MODE_LINE ||
+      state->fill_front == PIPE_POLYGON_MODE_POINT ||
+      state->fill_back == PIPE_POLYGON_MODE_LINE ||
+      state->fill_back == PIPE_POLYGON_MODE_POINT;
+
    if (state->clip_plane_enable != 0)
       cso->num_clip_plane_consts = util_logbase2(state->clip_plane_enable) + 1;
    else
@@ -1308,7 +1315,6 @@ iris_create_rasterizer_state(struct pipe_context *ctx,
       cl.APIMode = state->clip_halfz ? APIMODE_D3D : APIMODE_OGL;
       cl.GuardbandClipTestEnable = true;
       cl.ClipEnable = true;
-      cl.ViewportXYClipTestEnable = state->point_tri_clip;
       cl.MinimumPointWidth = 0.125;
       cl.MaximumPointWidth = 255.875;
 
@@ -4770,11 +4776,19 @@ iris_upload_dirty_render_state(struct iris_context *ice,
       struct iris_rasterizer_state *cso_rast = ice->state.cso_rast;
       struct pipe_framebuffer_state *cso_fb = &ice->state.framebuffer;
 
+      bool gs_or_tes = ice->shaders.prog[MESA_SHADER_GEOMETRY] ||
+                       ice->shaders.prog[MESA_SHADER_TESS_EVAL];
+      bool points_or_lines = cso_rast->fill_mode_point_or_line ||
+         (gs_or_tes ? ice->shaders.output_topology_is_points_or_lines
+                    : ice->state.prim_is_points_or_lines);
+
       uint32_t dynamic_clip[GENX(3DSTATE_CLIP_length)];
       iris_pack_command(GENX(3DSTATE_CLIP), &dynamic_clip, cl) {
          cl.StatisticsEnable = ice->state.statistics_counters_enabled;
          cl.ClipMode = cso_rast->rasterizer_discard ? CLIPMODE_REJECT_ALL
                                                     : CLIPMODE_NORMAL;
+         cl.ViewportXYClipTestEnable = !points_or_lines;
+
          if (wm_prog_data->barycentric_interp_modes &
              BRW_BARYCENTRIC_NONPERSPECTIVE_BITS)
             cl.NonPerspectiveBarycentricEnable = true;