iris: Fix surface states for Gen8 lowered-to-untype images
authorKenneth Graunke <kenneth@whitecape.org>
Wed, 26 Dec 2018 10:06:13 +0000 (02:06 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 21 Feb 2019 18:26:11 +0000 (10:26 -0800)
We have to use SURFTYPE_BUFFER and ISL_FORMAT_RAW for these.

src/gallium/drivers/iris/iris_state.c

index 5d1aaf97c41e96a50408659b82ae0e19d5cf7e35..f8ef3f82e791e627c76caa9eacdc94f8147c748f 100644 (file)
@@ -1512,7 +1512,7 @@ fill_buffer_surface_state(struct isl_device *isl_dev,
                           unsigned size)
 {
    const struct isl_format_layout *fmtl = isl_format_get_layout(format);
-   const unsigned cpp = fmtl->bpb / 8;
+   const unsigned cpp = format == ISL_FORMAT_RAW ? 1 : fmtl->bpb / 8;
 
    /* The ARB_texture_buffer_specification says:
     *
@@ -1808,17 +1808,30 @@ iris_set_shader_images(struct pipe_context *ctx,
          }
 
          isl_surf_usage_flags_t usage = ISL_SURF_USAGE_STORAGE_BIT;
-         enum isl_format isl_format =
+         enum isl_format isl_fmt =
             iris_format_for_usage(devinfo, img->format, usage).fmt;
 
-         if (img->shader_access & PIPE_IMAGE_ACCESS_READ)
-            isl_format = isl_lower_storage_image_format(devinfo, isl_format);
+         bool untyped_fallback = false;
+
+         if (img->shader_access & PIPE_IMAGE_ACCESS_READ) {
+            /* On Gen8, try to use typed surfaces reads (which support a
+             * limited number of formats), and if not possible, fall back
+             * to untyped reads.
+             */
+            untyped_fallback = GEN_GEN == 8 &&
+               !isl_has_matching_typed_storage_image_format(devinfo, isl_fmt);
+
+            if (untyped_fallback)
+               isl_fmt = ISL_FORMAT_RAW;
+            else
+               isl_fmt = isl_lower_storage_image_format(devinfo, isl_fmt);
+         }
 
          shs->image[start_slot + i].access = img->shader_access;
 
          if (res->base.target != PIPE_BUFFER) {
             struct isl_view view = {
-               .format = isl_format,
+               .format = isl_fmt,
                .base_level = img->u.tex.level,
                .levels = 1,
                .base_array_layer = img->u.tex.first_layer,
@@ -1827,13 +1840,19 @@ iris_set_shader_images(struct pipe_context *ctx,
                .usage = usage,
             };
 
-            fill_surface_state(&screen->isl_dev, map, res, &view);
+            if (untyped_fallback) {
+               fill_buffer_surface_state(&screen->isl_dev, res->bo, map,
+                                         isl_fmt, 0, res->bo->size);
+            } else {
+               fill_surface_state(&screen->isl_dev, map, res, &view);
+            }
+
             isl_surf_fill_image_param(&screen->isl_dev,
                                       &shs->image[start_slot + i].param,
                                       &res->surf, &view);
          } else {
             fill_buffer_surface_state(&screen->isl_dev, res->bo, map,
-                                      isl_format, img->u.buf.offset,
+                                      isl_fmt, img->u.buf.offset,
                                       img->u.buf.size);
             fill_buffer_image_param(&shs->image[start_slot + i].param,
                                     img->format, img->u.buf.size);