isl/state: Add support for OffsetX/Y in surface state
authorJason Ekstrand <jason.ekstrand@intel.com>
Wed, 8 Jun 2016 23:43:35 +0000 (16:43 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Fri, 15 Jul 2016 22:53:48 +0000 (15:53 -0700)
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Chad Versace <chad.versace@intel.com>
src/intel/isl/isl.h
src/intel/isl/isl_surface_state.c

index b2ce6f59cc5c5061efcd4c31cbc2f2d6c1d9717b..19673f899d99124a18729adf44f5a4cf5edcb6ae 100644 (file)
@@ -917,6 +917,9 @@ struct isl_surf_fill_state_info {
     * Valid values depend on hardware generation.
     */
    union isl_color_value clear_color;
+
+   /* Intra-tile offset */
+   uint16_t x_offset_sa, y_offset_sa;
 };
 
 struct isl_buffer_fill_state_info {
index dcec800b6402d7321b9947da91d08c3725951550..d1c8f17815a9f8bf6a2faaaedc8d2e6db790faaa 100644 (file)
@@ -402,6 +402,34 @@ isl_genX(surf_fill_state_s)(const struct isl_device *dev, void *state,
    s.MOCS = info->mocs;
 #endif
 
+#if GEN_GEN > 4 || GEN_IS_G4X
+   if (info->x_offset_sa != 0 || info->y_offset_sa != 0) {
+      /* There are fairly strict rules about when the offsets can be used.
+       * These are mostly taken from the Sky Lake PRM documentation for
+       * RENDER_SURFACE_STATE.
+       */
+      assert(info->surf->tiling != ISL_TILING_LINEAR);
+      assert(info->surf->dim == ISL_SURF_DIM_2D);
+      assert(isl_is_pow2(isl_format_get_layout(info->view->format)->bpb));
+      assert(info->surf->levels == 1);
+      assert(info->surf->logical_level0_px.array_len == 1);
+      assert(info->aux_usage == ISL_AUX_USAGE_NONE);
+#if GEN_GEN >= 7
+      s.SurfaceArray = false;
+#endif
+   }
+
+   const unsigned x_div = 4;
+   const unsigned y_div = GEN_GEN >= 8 ? 4 : 2;
+   assert(info->x_offset_sa % x_div == 0);
+   assert(info->y_offset_sa % y_div == 0);
+   s.XOffset = info->x_offset_sa / x_div;
+   s.YOffset = info->y_offset_sa / y_div;
+#else
+   assert(info->x_offset_sa == 0);
+   assert(info->y_offset_sa == 0);
+#endif
+
 #if GEN_GEN >= 7
    if (info->aux_surf && info->aux_usage != ISL_AUX_USAGE_NONE) {
       struct isl_tile_info tile_info;