anv/pipeline: Delete out-of-bounds fragment shader outputs
[mesa.git] / src / vulkan / anv_image.c
index 159af6d19b0458e794e3b37f7918cc9783bcd77c..0a412a3f8c668e40ab62620d7e77edef57ba6a7b 100644 (file)
 
 #include "anv_private.h"
 
-/* FIXME: We shouldn't be using the actual hardware enum values here.  They
- * change across gens.  Once we get that fixed, this include needs to go.
- */
-#include "gen8_pack.h"
-
 /**
- * The \a format argument is required and overrides any format found in struct
- * anv_image_create_info. Exactly one bit must be set in \a aspect.
+ * Exactly one bit must be set in \a aspect.
  */
 static isl_surf_usage_flags_t
-choose_isl_surf_usage(const struct anv_image_create_info *info,
+choose_isl_surf_usage(VkImageUsageFlags vk_usage,
                       VkImageAspectFlags aspect)
 {
-   const VkImageCreateInfo *vk_info = info->vk_info;
-   isl_surf_usage_flags_t isl_flags = 0;
+   isl_surf_usage_flags_t isl_usage = 0;
 
    /* FINISHME: Support aux surfaces */
-   isl_flags |= ISL_SURF_USAGE_DISABLE_AUX_BIT;
+   isl_usage |= ISL_SURF_USAGE_DISABLE_AUX_BIT;
 
-   if (vk_info->usage & VK_IMAGE_USAGE_SAMPLED_BIT)
-      isl_flags |= ISL_SURF_USAGE_TEXTURE_BIT;
+   if (vk_usage & VK_IMAGE_USAGE_SAMPLED_BIT)
+      isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
 
-   if (vk_info->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)
-      isl_flags |= ISL_SURF_USAGE_TEXTURE_BIT;
+   if (vk_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)
+      isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
 
-   if (vk_info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
-      isl_flags |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
+   if (vk_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
+      isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
 
-   if (vk_info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
-      isl_flags |= ISL_SURF_USAGE_CUBE_BIT;
+   if (vk_usage & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
+      isl_usage |= ISL_SURF_USAGE_CUBE_BIT;
 
-   if (vk_info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+   if (vk_usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
       switch (aspect) {
       default:
          unreachable("bad VkImageAspect");
       case VK_IMAGE_ASPECT_DEPTH_BIT:
-         isl_flags |= ISL_SURF_USAGE_DEPTH_BIT;
+         isl_usage |= ISL_SURF_USAGE_DEPTH_BIT;
          break;
       case VK_IMAGE_ASPECT_STENCIL_BIT:
-         isl_flags |= ISL_SURF_USAGE_STENCIL_BIT;
+         isl_usage |= ISL_SURF_USAGE_STENCIL_BIT;
          break;
       }
    }
 
-   if (vk_info->usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
+   if (vk_usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
       /* Meta implements transfers by sampling from the source image. */
-      isl_flags |= ISL_SURF_USAGE_TEXTURE_BIT;
+      isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
    }
 
-   if (vk_info->usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
+   if (vk_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
       /* Meta implements transfers by rendering into the destination image. */
-      isl_flags |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
+      isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
    }
 
-   return isl_flags;
+   return isl_usage;
 }
 
 /**
@@ -131,18 +124,36 @@ make_surface(const struct anv_device *dev,
 
    struct anv_surface *anv_surf = get_surface(image, aspect);
 
+   VkExtent3D extent;
+   switch (vk_info->imageType) {
+   case VK_IMAGE_TYPE_1D:
+      extent = (VkExtent3D) { vk_info->extent.width, 1, 1 };
+      break;
+   case VK_IMAGE_TYPE_2D:
+      extent = (VkExtent3D) { vk_info->extent.width, vk_info->extent.height, 1 };
+      break;
+   case VK_IMAGE_TYPE_3D:
+      extent = vk_info->extent;
+      break;
+   default:
+      unreachable("invalid image type");
+   }
+
+   image->extent = extent;
+
    ok = isl_surf_init(&dev->isl_dev, &anv_surf->isl,
       .dim = vk_to_isl_surf_dim[vk_info->imageType],
-      .format = anv_get_isl_format(vk_info->format, aspect),
-      .width = vk_info->extent.width,
-      .height = vk_info->extent.height,
-      .depth = vk_info->extent.depth,
+      .format = anv_get_isl_format(vk_info->format, aspect,
+                                   vk_info->tiling, NULL),
+      .width = extent.width,
+      .height = extent.height,
+      .depth = extent.depth,
       .levels = vk_info->mipLevels,
       .array_len = vk_info->arrayLayers,
       .samples = vk_info->samples,
       .min_alignment = 0,
       .min_pitch = 0,
-      .usage = choose_isl_surf_usage(anv_info, aspect),
+      .usage = choose_isl_surf_usage(image->usage, aspect),
       .tiling_flags = tiling_flags);
 
    /* isl_surf_init() will fail only if provided invalid input. Invalid input
@@ -157,21 +168,42 @@ make_surface(const struct anv_device *dev,
    return VK_SUCCESS;
 }
 
+/**
+ * Parameter @a format is required and overrides VkImageCreateInfo::format.
+ */
 static VkImageUsageFlags
-anv_image_get_full_usage(const VkImageCreateInfo *info)
+anv_image_get_full_usage(const VkImageCreateInfo *info,
+                         const struct anv_format *format)
 {
    VkImageUsageFlags usage = info->usage;
 
+   if (info->samples > 1 &&
+       (usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) {
+      /* Meta will resolve the image by binding it as a texture. */
+      usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
+   }
+
    if (usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
       /* Meta will transfer from the image by binding it as a texture. */
       usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
    }
 
    if (usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
-      /* Meta will transfer to the image by binding it as a color attachment,
-       * even if the image format is not a color format.
+      /* For non-clear transfer operations, meta will transfer to the image by
+       * binding it as a color attachment, even if the image format is not
+       * a color format.
        */
       usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+
+      if (anv_format_is_depth_or_stencil(format)) {
+         /* vkCmdClearDepthStencilImage() only requires that
+          * VK_IMAGE_USAGE_TRANSFER_SRC_BIT be set. In particular, it does
+          * not require VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT. Meta
+          * clears the image, though, by binding it as a depthstencil
+          * attachment.
+          */
+         usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+      }
    }
 
    return usage;
@@ -186,13 +218,14 @@ anv_image_create(VkDevice _device,
    ANV_FROM_HANDLE(anv_device, device, _device);
    const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
    struct anv_image *image = NULL;
+   const struct anv_format *format = anv_format_for_vk_format(pCreateInfo->format);
    VkResult r;
 
    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
 
    anv_assert(pCreateInfo->mipLevels > 0);
    anv_assert(pCreateInfo->arrayLayers > 0);
-   anv_assert(pCreateInfo->samples == VK_SAMPLE_COUNT_1_BIT);
+   anv_assert(pCreateInfo->samples > 0);
    anv_assert(pCreateInfo->extent.width > 0);
    anv_assert(pCreateInfo->extent.height > 0);
    anv_assert(pCreateInfo->extent.depth > 0);
@@ -205,30 +238,21 @@ anv_image_create(VkDevice _device,
    memset(image, 0, sizeof(*image));
    image->type = pCreateInfo->imageType;
    image->extent = pCreateInfo->extent;
-   image->format = anv_format_for_vk_format(pCreateInfo->format);
+   image->vk_format = pCreateInfo->format;
+   image->format = format;
    image->levels = pCreateInfo->mipLevels;
    image->array_size = pCreateInfo->arrayLayers;
-   image->usage = anv_image_get_full_usage(pCreateInfo);
-
-   if (image->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
-      image->needs_nonrt_surface_state = true;
-   }
-
-   if (image->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
-      image->needs_color_rt_surface_state = true;
-   }
+   image->samples = pCreateInfo->samples;
+   image->usage = anv_image_get_full_usage(pCreateInfo, format);
+   image->tiling = pCreateInfo->tiling;
 
-   if (image->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
-      image->needs_storage_surface_state = true;
-   }
-
-   if (likely(anv_format_is_color(image->format))) {
+   if (likely(anv_format_is_color(format))) {
       r = make_surface(device, image, create_info,
                        VK_IMAGE_ASPECT_COLOR_BIT);
       if (r != VK_SUCCESS)
          goto fail;
    } else {
-      if (image->format->depth_format) {
+      if (image->format->has_depth) {
          r = make_surface(device, image, create_info,
                           VK_IMAGE_ASPECT_DEPTH_BIT);
          if (r != VK_SUCCESS)
@@ -293,6 +317,7 @@ anv_surface_get_subresource_layout(struct anv_image *image,
    layout->offset = surface->offset;
    layout->rowPitch = surface->isl.row_pitch;
    layout->depthPitch = isl_surf_get_array_pitch(&surface->isl);
+   layout->arrayPitch = isl_surf_get_array_pitch(&surface->isl);
    layout->size = surface->isl.size;
 }
 
@@ -374,9 +399,9 @@ anv_validate_CreateImageView(VkDevice _device,
    /* Validate format. */
    if (subresource->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
       assert(subresource->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
-      assert(!image->format->depth_format);
+      assert(!image->format->has_depth);
       assert(!image->format->has_stencil);
-      assert(!view_format_info->depth_format);
+      assert(!view_format_info->has_depth);
       assert(!view_format_info->has_stencil);
       assert(view_format_info->isl_layout->bs ==
              image->format->isl_layout->bs);
@@ -384,8 +409,8 @@ anv_validate_CreateImageView(VkDevice _device,
       assert((subresource->aspectMask & ~ds_flags) == 0);
 
       if (subresource->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) {
-         assert(image->format->depth_format);
-         assert(view_format_info->depth_format);
+         assert(image->format->has_depth);
+         assert(view_format_info->has_depth);
          assert(view_format_info->isl_layout->bs ==
                 image->format->isl_layout->bs);
       }
@@ -402,14 +427,94 @@ anv_validate_CreateImageView(VkDevice _device,
    return anv_CreateImageView(_device, pCreateInfo, pAllocator, pView);
 }
 
+void
+anv_fill_image_surface_state(struct anv_device *device, struct anv_state state,
+                             struct anv_image_view *iview,
+                             const VkImageViewCreateInfo *pCreateInfo,
+                             VkImageUsageFlagBits usage)
+{
+   switch (device->info.gen) {
+   case 7:
+      if (device->info.is_haswell)
+         gen75_fill_image_surface_state(device, state.map, iview,
+                                        pCreateInfo, usage);
+      else
+         gen7_fill_image_surface_state(device, state.map, iview,
+                                       pCreateInfo, usage);
+      break;
+   case 8:
+      gen8_fill_image_surface_state(device, state.map, iview,
+                                    pCreateInfo, usage);
+      break;
+   case 9:
+      gen9_fill_image_surface_state(device, state.map, iview,
+                                    pCreateInfo, usage);
+      break;
+   default:
+      unreachable("unsupported gen\n");
+   }
+
+   if (!device->info.has_llc)
+      anv_state_clflush(state);
+}
+
+static struct anv_state
+alloc_surface_state(struct anv_device *device,
+                    struct anv_cmd_buffer *cmd_buffer)
+{
+      if (cmd_buffer) {
+         return anv_cmd_buffer_alloc_surface_state(cmd_buffer);
+      } else {
+         return anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
+      }
+}
+
+static bool
+has_matching_storage_typed_format(const struct anv_device *device,
+                                  enum isl_format format)
+{
+   return (isl_format_get_layout(format)->bs <= 4 ||
+           (isl_format_get_layout(format)->bs <= 8 &&
+            (device->info.gen >= 8 || device->info.is_haswell)) ||
+           device->info.gen >= 9);
+}
+
+static VkComponentSwizzle
+remap_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component,
+              struct anv_format_swizzle format_swizzle)
+{
+   if (swizzle == VK_COMPONENT_SWIZZLE_IDENTITY)
+      swizzle = component;
+
+   switch (swizzle) {
+   case VK_COMPONENT_SWIZZLE_ZERO:
+      return VK_COMPONENT_SWIZZLE_ZERO;
+   case VK_COMPONENT_SWIZZLE_ONE:
+      return VK_COMPONENT_SWIZZLE_ONE;
+   case VK_COMPONENT_SWIZZLE_R:
+      return VK_COMPONENT_SWIZZLE_R + format_swizzle.r;
+   case VK_COMPONENT_SWIZZLE_G:
+      return VK_COMPONENT_SWIZZLE_R + format_swizzle.g;
+   case VK_COMPONENT_SWIZZLE_B:
+      return VK_COMPONENT_SWIZZLE_R + format_swizzle.b;
+   case VK_COMPONENT_SWIZZLE_A:
+      return VK_COMPONENT_SWIZZLE_R + format_swizzle.a;
+   default:
+      unreachable("Invalid swizzle");
+   }
+}
+
 void
 anv_image_view_init(struct anv_image_view *iview,
                     struct anv_device *device,
                     const VkImageViewCreateInfo* pCreateInfo,
-                    struct anv_cmd_buffer *cmd_buffer)
+                    struct anv_cmd_buffer *cmd_buffer,
+                    uint32_t offset)
 {
    ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
    const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
+   VkImageViewCreateInfo mCreateInfo;
+   memcpy(&mCreateInfo, pCreateInfo, sizeof(VkImageViewCreateInfo));
 
    assert(range->layerCount > 0);
    assert(range->baseMipLevel < image->levels);
@@ -431,21 +536,94 @@ anv_image_view_init(struct anv_image_view *iview,
       break;
    }
 
-   switch (device->info.gen) {
-   case 7:
-      if (device->info.is_haswell)
-         gen75_image_view_init(iview, device, pCreateInfo, cmd_buffer);
+   struct anv_surface *surface =
+      anv_image_get_surface_for_aspect_mask(image, range->aspectMask);
+
+   iview->image = image;
+   iview->bo = image->bo;
+   iview->offset = image->offset + surface->offset + offset;
+
+   iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask;
+   iview->vk_format = pCreateInfo->format;
+
+   struct anv_format_swizzle swizzle;
+   iview->format = anv_get_isl_format(pCreateInfo->format, iview->aspect_mask,
+                                      image->tiling, &swizzle);
+   iview->swizzle.r = remap_swizzle(pCreateInfo->components.r,
+                                    VK_COMPONENT_SWIZZLE_R, swizzle);
+   iview->swizzle.g = remap_swizzle(pCreateInfo->components.g,
+                                    VK_COMPONENT_SWIZZLE_G, swizzle);
+   iview->swizzle.b = remap_swizzle(pCreateInfo->components.b,
+                                    VK_COMPONENT_SWIZZLE_B, swizzle);
+   iview->swizzle.a = remap_swizzle(pCreateInfo->components.a,
+                                    VK_COMPONENT_SWIZZLE_A, swizzle);
+
+   iview->base_layer = range->baseArrayLayer;
+   iview->base_mip = range->baseMipLevel;
+
+   if (!isl_format_is_compressed(iview->format) &&
+       isl_format_is_compressed(image->format->isl_format)) {
+      /* Scale the ImageView extent by the backing Image. This is used
+       * internally when an uncompressed ImageView is created on a
+       * compressed Image. The ImageView can therefore be used for copying
+       * data from a source Image to a destination Image.
+       */
+      const struct isl_format_layout * isl_layout = image->format->isl_layout;
+
+      iview->level_0_extent.depth  = anv_minify(image->extent.depth, range->baseMipLevel);
+      iview->level_0_extent.depth  = DIV_ROUND_UP(iview->level_0_extent.depth, isl_layout->bd);
+
+      iview->level_0_extent.height = isl_surf_get_array_pitch_el_rows(&surface->isl) * image->array_size;
+      iview->level_0_extent.width  = isl_surf_get_row_pitch_el(&surface->isl);
+      mCreateInfo.subresourceRange.baseMipLevel = 0;
+      mCreateInfo.subresourceRange.baseArrayLayer = 0;
+   } else {
+      iview->level_0_extent.width  = image->extent.width;
+      iview->level_0_extent.height = image->extent.height;
+      iview->level_0_extent.depth  = image->extent.depth;
+   }
+
+   iview->extent = (VkExtent3D) {
+      .width  = anv_minify(iview->level_0_extent.width , range->baseMipLevel),
+      .height = anv_minify(iview->level_0_extent.height, range->baseMipLevel),
+      .depth  = anv_minify(iview->level_0_extent.depth , range->baseMipLevel),
+   };
+
+   if (image->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
+      iview->sampler_surface_state = alloc_surface_state(device, cmd_buffer);
+
+      anv_fill_image_surface_state(device, iview->sampler_surface_state,
+                                   iview, &mCreateInfo,
+                                   VK_IMAGE_USAGE_SAMPLED_BIT);
+   } else {
+      iview->sampler_surface_state.alloc_size = 0;
+   }
+
+   if (image->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
+      iview->color_rt_surface_state = alloc_surface_state(device, cmd_buffer);
+
+      anv_fill_image_surface_state(device, iview->color_rt_surface_state,
+                                   iview, &mCreateInfo,
+                                   VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
+   } else {
+      iview->color_rt_surface_state.alloc_size = 0;
+   }
+
+   if (image->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
+      iview->storage_surface_state = alloc_surface_state(device, cmd_buffer);
+
+      if (has_matching_storage_typed_format(device, iview->format))
+         anv_fill_image_surface_state(device, iview->storage_surface_state,
+                                      iview, &mCreateInfo,
+                                      VK_IMAGE_USAGE_STORAGE_BIT);
       else
-         gen7_image_view_init(iview, device, pCreateInfo, cmd_buffer);
-      break;
-   case 8:
-      gen8_image_view_init(iview, device, pCreateInfo, cmd_buffer);
-      break;
-   case 9:
-      gen9_image_view_init(iview, device, pCreateInfo, cmd_buffer);
-      break;
-   default:
-      unreachable("unsupported gen\n");
+         anv_fill_buffer_surface_state(device, iview->storage_surface_state,
+                                       ISL_FORMAT_RAW,
+                                       iview->offset,
+                                       iview->bo->size - iview->offset, 1);
+
+   } else {
+      iview->storage_surface_state.alloc_size = 0;
    }
 }
 
@@ -463,7 +641,7 @@ anv_CreateImageView(VkDevice _device,
    if (view == NULL)
       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
-   anv_image_view_init(view, device, pCreateInfo, NULL);
+   anv_image_view_init(view, device, pCreateInfo, NULL, 0);
 
    *pView = anv_image_view_to_handle(view);
 
@@ -477,17 +655,17 @@ anv_DestroyImageView(VkDevice _device, VkImageView _iview,
    ANV_FROM_HANDLE(anv_device, device, _device);
    ANV_FROM_HANDLE(anv_image_view, iview, _iview);
 
-   if (iview->image->needs_color_rt_surface_state) {
+   if (iview->color_rt_surface_state.alloc_size > 0) {
       anv_state_pool_free(&device->surface_state_pool,
                           iview->color_rt_surface_state);
    }
 
-   if (iview->image->needs_nonrt_surface_state) {
+   if (iview->sampler_surface_state.alloc_size > 0) {
       anv_state_pool_free(&device->surface_state_pool,
-                          iview->nonrt_surface_state);
+                          iview->sampler_surface_state);
    }
 
-   if (iview->image->needs_storage_surface_state) {
+   if (iview->storage_surface_state.alloc_size > 0) {
       anv_state_pool_free(&device->surface_state_pool,
                           iview->storage_surface_state);
    }
@@ -513,19 +691,20 @@ anv_CreateBufferView(VkDevice _device,
    const struct anv_format *format =
       anv_format_for_vk_format(pCreateInfo->format);
 
-   view->format = format->surface_format;
+   view->format = format->isl_format;
    view->bo = buffer->bo;
    view->offset = buffer->offset + pCreateInfo->offset;
-   view->range = pCreateInfo->range;
+   view->range = pCreateInfo->range == VK_WHOLE_SIZE ?
+                 buffer->size - view->offset : pCreateInfo->range;
 
    if (buffer->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) {
       view->surface_state =
          anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
 
-      anv_fill_buffer_surface_state(device, view->surface_state.map,
+      anv_fill_buffer_surface_state(device, view->surface_state,
                                     view->format,
-                                    view->offset, pCreateInfo->range,
-                                    format->isl_layout->bpb / 8);
+                                    view->offset, view->range,
+                                    format->isl_layout->bs);
    } else {
       view->surface_state = (struct anv_state){ 0 };
    }
@@ -535,12 +714,16 @@ anv_CreateBufferView(VkDevice _device,
          anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
 
       enum isl_format storage_format =
-         isl_lower_storage_image_format(&device->isl_dev, view->format);
+         has_matching_storage_typed_format(device, view->format) ?
+         isl_lower_storage_image_format(&device->isl_dev, view->format) :
+         ISL_FORMAT_RAW;
 
-      anv_fill_buffer_surface_state(device, view->storage_surface_state.map,
+      anv_fill_buffer_surface_state(device, view->storage_surface_state,
                                     storage_format,
-                                    view->offset, pCreateInfo->range,
-                                    format->isl_layout->bpb / 8);
+                                    view->offset, view->range,
+                                    (storage_format == ISL_FORMAT_RAW ? 1 :
+                                     format->isl_layout->bs));
+
    } else {
       view->storage_surface_state = (struct anv_state){ 0 };
    }
@@ -578,10 +761,9 @@ anv_image_get_surface_for_aspect_mask(struct anv_image *image, VkImageAspectFlag
        * Meta attaches all destination surfaces as color render targets. Guess
        * what surface the Meta Dragons really want.
        */
-      if (image->format->depth_format && image->format->has_stencil) {
-         anv_finishme("combined depth stencil formats");
+      if (image->format->has_depth && image->format->has_stencil) {
          return &image->depth_surface;
-      } else if (image->format->depth_format) {
+      } else if (image->format->has_depth) {
          return &image->depth_surface;
       } else if (image->format->has_stencil) {
          return &image->stencil_surface;
@@ -590,22 +772,26 @@ anv_image_get_surface_for_aspect_mask(struct anv_image *image, VkImageAspectFlag
       }
       break;
    case VK_IMAGE_ASPECT_DEPTH_BIT:
-      assert(image->format->depth_format);
+      assert(image->format->has_depth);
       return &image->depth_surface;
    case VK_IMAGE_ASPECT_STENCIL_BIT:
       assert(image->format->has_stencil);
       return &image->stencil_surface;
    case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
-      if (image->format->depth_format && image->format->has_stencil) {
-         /* FINISHME: The Vulkan spec (git a511ba2) requires support for combined
-          * depth stencil formats. Specifically, it states:
+      if (image->format->has_depth && image->format->has_stencil) {
+         /* FINISHME: The Vulkan spec (git a511ba2) requires support for
+          * combined depth stencil formats. Specifically, it states:
           *
           *    At least one of ename:VK_FORMAT_D24_UNORM_S8_UINT or
           *    ename:VK_FORMAT_D32_SFLOAT_S8_UINT must be supported.
+          *
+          * Image views with both depth and stencil aspects are only valid for
+          * render target attachments, in which case
+          * cmd_buffer_emit_depth_stencil() will pick out both the depth and
+          * stencil surfaces from the underlying surface.
           */
-         anv_finishme("combined depthstencil aspect");
          return &image->depth_surface;
-      } else if (image->format->depth_format) {
+      } else if (image->format->has_depth) {
          return &image->depth_surface;
       } else if (image->format->has_stencil) {
          return &image->stencil_surface;
@@ -617,13 +803,100 @@ anv_image_get_surface_for_aspect_mask(struct anv_image *image, VkImageAspectFlag
    }
 }
 
+static void
+image_param_defaults(struct brw_image_param *param)
+{
+   memset(param, 0, sizeof *param);
+   /* Set the swizzling shifts to all-ones to effectively disable swizzling --
+    * See emit_address_calculation() in brw_fs_surface_builder.cpp for a more
+    * detailed explanation of these parameters.
+    */
+   param->swizzling[0] = 0xff;
+   param->swizzling[1] = 0xff;
+}
+
 void
 anv_image_view_fill_image_param(struct anv_device *device,
                                 struct anv_image_view *view,
                                 struct brw_image_param *param)
 {
-   memset(param, 0, sizeof *param);
-   anv_finishme("Actually fill out brw_image_param");
+   image_param_defaults(param);
+
+   const struct isl_surf *surf = &view->image->color_surface.isl;
+   const int cpp = isl_format_get_layout(surf->format)->bs;
+   const struct isl_extent3d image_align_sa =
+      isl_surf_get_image_alignment_sa(surf);
+
+   param->size[0] = view->extent.width;
+   param->size[1] = view->extent.height;
+   if (surf->dim == ISL_SURF_DIM_3D) {
+      param->size[2] = view->extent.depth;
+   } else {
+      param->size[2] = surf->logical_level0_px.array_len - view->base_layer;
+   }
+
+   isl_surf_get_image_offset_el(surf, view->base_mip, view->base_layer, 0,
+                                &param->offset[0],  &param->offset[1]);
+
+   param->stride[0] = cpp;
+   param->stride[1] = surf->row_pitch / cpp;
+
+   if (device->info.gen < 9 && surf->dim == ISL_SURF_DIM_3D) {
+      param->stride[2] = util_align_npot(param->size[0], image_align_sa.w);
+      param->stride[3] = util_align_npot(param->size[1], image_align_sa.h);
+   } else {
+      param->stride[2] = 0;
+      param->stride[3] = isl_surf_get_array_pitch_el_rows(surf);
+   }
+
+   switch (surf->tiling) {
+   case ISL_TILING_LINEAR:
+      /* image_param_defaults is good enough */
+      break;
+
+   case ISL_TILING_X:
+      /* An X tile is a rectangular block of 512x8 bytes. */
+      param->tiling[0] = util_logbase2(512 / cpp);
+      param->tiling[1] = util_logbase2(8);
+
+      if (device->isl_dev.has_bit6_swizzling) {
+         /* Right shifts required to swizzle bits 9 and 10 of the memory
+          * address with bit 6.
+          */
+         param->swizzling[0] = 3;
+         param->swizzling[1] = 4;
+      }
+      break;
+
+   case ISL_TILING_Y0:
+      /* The layout of a Y-tiled surface in memory isn't really fundamentally
+       * different to the layout of an X-tiled surface, we simply pretend that
+       * the surface is broken up in a number of smaller 16Bx32 tiles, each
+       * one arranged in X-major order just like is the case for X-tiling.
+       */
+      param->tiling[0] = util_logbase2(16 / cpp);
+      param->tiling[1] = util_logbase2(32);
+
+      if (device->isl_dev.has_bit6_swizzling) {
+         /* Right shift required to swizzle bit 9 of the memory address with
+          * bit 6.
+          */
+         param->swizzling[0] = 3;
+         param->swizzling[1] = 0xff;
+      }
+      break;
+
+   default:
+      assert(!"Unhandled storage image tiling");
+   }
+
+   /* 3D textures are arranged in 2D in memory with 2^lod slices per row.  The
+    * address calculation algorithm (emit_address_calculation() in
+    * brw_fs_surface_builder.cpp) handles this as a sort of tiling with
+    * modulus equal to the LOD.
+    */
+   param->tiling[2] = (device->info.gen < 9 && surf->dim == ISL_SURF_DIM_3D ?
+                       view->base_mip : 0);
 }
 
 void
@@ -631,13 +904,8 @@ anv_buffer_view_fill_image_param(struct anv_device *device,
                                  struct anv_buffer_view *view,
                                  struct brw_image_param *param)
 {
-   /* Set the swizzling shifts to all-ones to effectively disable swizzling --
-    * See emit_address_calculation() in brw_fs_surface_builder.cpp for a more
-    * detailed explanation of these parameters.
-    */
-   param->swizzling[0] = 0xff;
-   param->swizzling[1] = 0xff;
+   image_param_defaults(param);
 
-   param->stride[0] = isl_format_layouts[view->format].bpb / 8;
+   param->stride[0] = isl_format_layouts[view->format].bs;
    param->size[0] = view->range / param->stride[0];
 }