iris: Handle vertex shader with window space position
authorDanylo Piliaiev <danylo.piliaiev@globallogic.com>
Thu, 25 Jul 2019 10:09:08 +0000 (13:09 +0300)
committerKenneth Graunke <kenneth@whitecape.org>
Tue, 6 Aug 2019 20:25:35 +0000 (20:25 +0000)
Iris advertises support for PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION
so let's actually implement it.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=110657

Signed-off-by: Danylo Piliaiev <danylo.piliaiev@globallogic.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/gallium/drivers/iris/iris_context.h
src/gallium/drivers/iris/iris_program.c
src/gallium/drivers/iris/iris_state.c

index 8a098f50b201de7f84fc5c7b43889c2b1632368a..f25c91fb317042e2bfd7848a65e7afbf48d6f445 100644 (file)
@@ -631,6 +631,8 @@ struct iris_context {
       bool prim_is_points_or_lines;
       uint8_t vertices_per_patch;
 
+      bool window_space_position;
+
       /** The last compute grid size */
       uint32_t last_grid[3];
       /** Reference to the BO containing the compute grid size */
index d5986f4809c65499628cbb6199a568744a162124..48b9f4397c9170868c22434418bcf50d19d1d7ca 100644 (file)
@@ -2232,6 +2232,20 @@ bind_shader_state(struct iris_context *ice,
 static void
 iris_bind_vs_state(struct pipe_context *ctx, void *state)
 {
+   struct iris_context *ice = (struct iris_context *)ctx;
+   struct iris_uncompiled_shader *new_ish = state;
+
+   if (new_ish &&
+       ice->state.window_space_position !=
+       new_ish->nir->info.vs.window_space_position) {
+      ice->state.window_space_position =
+         new_ish->nir->info.vs.window_space_position;
+
+      ice->state.dirty |= IRIS_DIRTY_CLIP |
+                          IRIS_DIRTY_RASTER |
+                          IRIS_DIRTY_CC_VIEWPORT;
+   }
+
    bind_shader_state((void *) ctx, state, MESA_SHADER_VERTEX);
 }
 
index 13522e5d0c40d28fdd9c2e028805de0a20d77624..7932df23e3da1665f7034563075990b52ecde30a 100644 (file)
@@ -1204,7 +1204,6 @@ iris_create_rasterizer_state(struct pipe_context *ctx,
 
    iris_pack_command(GENX(3DSTATE_SF), cso->sf, sf) {
       sf.StatisticsEnable = true;
-      sf.ViewportTransformEnable = true;
       sf.AALineDistanceMode = AALINEDISTANCE_TRUE;
       sf.LineEndCapAntialiasingRegionWidth =
          state->line_smooth ? _10pixels : _05pixels;
@@ -4335,6 +4334,18 @@ iris_update_surface_base_address(struct iris_batch *batch,
    batch->last_surface_base_address = binder->bo->gtt_offset;
 }
 
+static inline void
+iris_viewport_zmin_zmax(const struct pipe_viewport_state *vp, bool halfz,
+                        bool window_space_position, float *zmin, float *zmax)
+{
+   if (window_space_position) {
+      *zmin = 0.f;
+      *zmax = 1.f;
+      return;
+   }
+   util_viewport_zmin_zmax(vp, halfz, zmin, zmax);
+}
+
 static void
 iris_upload_dirty_render_state(struct iris_context *ice,
                                struct iris_batch *batch,
@@ -4362,7 +4373,8 @@ iris_upload_dirty_render_state(struct iris_context *ice,
                       GENX(CC_VIEWPORT_length), 32, &cc_vp_address);
       for (int i = 0; i < ice->state.num_viewports; i++) {
          float zmin, zmax;
-         util_viewport_zmin_zmax(&ice->state.viewports[i],
+         iris_viewport_zmin_zmax(&ice->state.viewports[i],
+                                 ice->state.window_space_position,
                                  cso_rast->clip_halfz, &zmin, &zmax);
          if (cso_rast->depth_clip_near)
             zmin = 0.0;
@@ -4773,8 +4785,14 @@ iris_upload_dirty_render_state(struct iris_context *ice,
       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;
+         if (cso_rast->rasterizer_discard)
+            cl.ClipMode = CLIPMODE_REJECT_ALL;
+         else if (ice->state.window_space_position)
+            cl.ClipMode = CLIPMODE_ACCEPT_ALL;
+         else
+            cl.ClipMode = CLIPMODE_NORMAL;
+
+         cl.PerspectiveDivideDisable = ice->state.window_space_position;
          cl.ViewportXYClipTestEnable = !points_or_lines;
 
          if (wm_prog_data->barycentric_interp_modes &
@@ -4791,8 +4809,13 @@ iris_upload_dirty_render_state(struct iris_context *ice,
    if (dirty & IRIS_DIRTY_RASTER) {
       struct iris_rasterizer_state *cso = ice->state.cso_rast;
       iris_batch_emit(batch, cso->raster, sizeof(cso->raster));
-      iris_batch_emit(batch, cso->sf, sizeof(cso->sf));
 
+      uint32_t dynamic_sf[GENX(3DSTATE_SF_length)];
+      iris_pack_command(GENX(3DSTATE_SF), &dynamic_sf, sf) {
+         sf.ViewportTransformEnable = !ice->state.window_space_position;
+      }
+      iris_emit_merge(batch, cso->sf, dynamic_sf,
+                      ARRAY_SIZE(dynamic_sf));
    }
 
    if (dirty & IRIS_DIRTY_WM) {