iris: Clamp viewport extents to the framebuffer dimensions
authorKenneth Graunke <kenneth@whitecape.org>
Mon, 3 Dec 2018 10:02:49 +0000 (02:02 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 21 Feb 2019 18:26:10 +0000 (10:26 -0800)
Fixes arb_framebuffer_no_attachments-query's resize subtest.

src/gallium/drivers/iris/iris_state.c

index 7af6cf2d04d27c20396f065101a220d79e71e892..d86107fad58db10bb331f625efe153f7c0cd9710 100644 (file)
@@ -765,9 +765,6 @@ struct iris_depth_buffer_state {
  * packets which vary by generation.
  */
 struct iris_genx_state {
-   /** SF_CLIP_VIEWPORT */
-   uint32_t sf_cl_vp[GENX(SF_CLIP_VIEWPORT_length) * IRIS_MAX_VIEWPORTS];
-
    struct iris_vertex_buffer_state vertex_buffers;
    struct iris_depth_buffer_state depth_buffer;
 
@@ -1989,37 +1986,8 @@ iris_set_viewport_states(struct pipe_context *ctx,
                          const struct pipe_viewport_state *states)
 {
    struct iris_context *ice = (struct iris_context *) ctx;
-   struct iris_genx_state *genx = ice->state.genx;
-   uint32_t *vp_map =
-      &genx->sf_cl_vp[start_slot * GENX(SF_CLIP_VIEWPORT_length)];
 
-   for (unsigned i = 0; i < count; i++) {
-      const struct pipe_viewport_state *state = &states[i];
-
-      memcpy(&ice->state.viewports[start_slot + i], state, sizeof(*state));
-
-      iris_pack_state(GENX(SF_CLIP_VIEWPORT), vp_map, vp) {
-         vp.ViewportMatrixElementm00 = state->scale[0];
-         vp.ViewportMatrixElementm11 = state->scale[1];
-         vp.ViewportMatrixElementm22 = state->scale[2];
-         vp.ViewportMatrixElementm30 = state->translate[0];
-         vp.ViewportMatrixElementm31 = state->translate[1];
-         vp.ViewportMatrixElementm32 = state->translate[2];
-         /* XXX: in i965 this is computed based on the drawbuffer size,
-          * but we don't have that here...
-          */
-         vp.XMinClipGuardband = -1.0;
-         vp.XMaxClipGuardband = 1.0;
-         vp.YMinClipGuardband = -1.0;
-         vp.YMaxClipGuardband = 1.0;
-         vp.XMinViewPort = viewport_extent(state, 0, -1.0f);
-         vp.XMaxViewPort = viewport_extent(state, 0,  1.0f) - 1;
-         vp.YMinViewPort = viewport_extent(state, 1, -1.0f);
-         vp.YMaxViewPort = viewport_extent(state, 1,  1.0f) - 1;
-      }
-
-      vp_map += GENX(SF_CLIP_VIEWPORT_length);
-   }
+   memcpy(&ice->state.viewports[start_slot], states, sizeof(*states) * count);
 
    ice->state.dirty |= IRIS_DIRTY_SF_CL_VIEWPORT;
 
@@ -2059,6 +2027,10 @@ iris_set_framebuffer_state(struct pipe_context *ctx,
       ice->state.dirty |= IRIS_DIRTY_CLIP;
    }
 
+   if (cso->width != state->width || cso->height != state->height) {
+      ice->state.dirty |= IRIS_DIRTY_SF_CL_VIEWPORT;
+   }
+
    util_copy_framebuffer_state(cso, state);
    cso->samples = samples;
 
@@ -3970,12 +3942,47 @@ iris_upload_dirty_render_state(struct iris_context *ice,
    }
 
    if (dirty & IRIS_DIRTY_SF_CL_VIEWPORT) {
+      struct pipe_framebuffer_state *cso_fb = &ice->state.framebuffer;
+      uint32_t sf_cl_vp_address;
+      uint32_t *vp_map =
+         stream_state(batch, ice->state.dynamic_uploader,
+                      &ice->state.last_res.sf_cl_vp,
+                      4 * ice->state.num_viewports *
+                      GENX(SF_CLIP_VIEWPORT_length), 64, &sf_cl_vp_address);
+
+      for (unsigned i = 0; i < ice->state.num_viewports; i++) {
+         const struct pipe_viewport_state *state = &ice->state.viewports[i];
+
+         float vp_xmin = viewport_extent(state, 0, -1.0f);
+         float vp_xmax = viewport_extent(state, 0,  1.0f);
+         float vp_ymin = viewport_extent(state, 1, -1.0f);
+         float vp_ymax = viewport_extent(state, 1,  1.0f);
+
+         iris_pack_state(GENX(SF_CLIP_VIEWPORT), vp_map, vp) {
+            vp.ViewportMatrixElementm00 = state->scale[0];
+            vp.ViewportMatrixElementm11 = state->scale[1];
+            vp.ViewportMatrixElementm22 = state->scale[2];
+            vp.ViewportMatrixElementm30 = state->translate[0];
+            vp.ViewportMatrixElementm31 = state->translate[1];
+            vp.ViewportMatrixElementm32 = state->translate[2];
+            /* XXX: in i965 this is computed based on the drawbuffer size,
+             * but we don't have that here...
+             */
+            vp.XMinClipGuardband = -1.0;
+            vp.XMaxClipGuardband = 1.0;
+            vp.YMinClipGuardband = -1.0;
+            vp.YMaxClipGuardband = 1.0;
+            vp.XMinViewPort = MAX2(vp_xmin, 0);
+            vp.XMaxViewPort = MIN2(vp_xmax, cso_fb->width) - 1;
+            vp.YMinViewPort = MAX2(vp_ymin, 0);
+            vp.YMaxViewPort = MIN2(vp_ymax, cso_fb->height) - 1;
+         }
+
+         vp_map += GENX(SF_CLIP_VIEWPORT_length);
+      }
+
       iris_emit_cmd(batch, GENX(3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP), ptr) {
-         ptr.SFClipViewportPointer =
-            emit_state(batch, ice->state.dynamic_uploader,
-                       &ice->state.last_res.sf_cl_vp,
-                       genx->sf_cl_vp, 4 * GENX(SF_CLIP_VIEWPORT_length) *
-                       ice->state.num_viewports, 64);
+         ptr.SFClipViewportPointer = sf_cl_vp_address;
       }
    }