gallium: add separate PIPE_CAP_INT64_DIVMOD
[mesa.git] / src / intel / vulkan / anv_image.c
index 77dcd46236e2e50233d6b1754ee85f32ce993939..e59ef4dbb6759ebe5d7786bc7b5e282e5f5bbc31 100644 (file)
@@ -41,9 +41,6 @@ choose_isl_surf_usage(VkImageUsageFlags vk_usage,
 {
    isl_surf_usage_flags_t isl_usage = 0;
 
-   /* FINISHME: Support aux surfaces */
-   isl_usage |= ISL_SURF_USAGE_DISABLE_AUX_BIT;
-
    if (vk_usage & VK_IMAGE_USAGE_SAMPLED_BIT)
       isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
 
@@ -56,27 +53,33 @@ choose_isl_surf_usage(VkImageUsageFlags vk_usage,
    if (vk_usage & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
       isl_usage |= ISL_SURF_USAGE_CUBE_BIT;
 
-   if (vk_usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
-      switch (aspect) {
-      default:
-         unreachable("bad VkImageAspect");
-      case VK_IMAGE_ASPECT_DEPTH_BIT:
-         isl_usage &= ~ISL_SURF_USAGE_DISABLE_AUX_BIT;
-         isl_usage |= ISL_SURF_USAGE_DEPTH_BIT;
-         break;
-      case VK_IMAGE_ASPECT_STENCIL_BIT:
-         isl_usage |= ISL_SURF_USAGE_STENCIL_BIT;
-         break;
-      }
+   /* Even if we're only using it for transfer operations, clears to depth and
+    * stencil images happen as depth and stencil so they need the right ISL
+    * usage bits or else things will fall apart.
+    */
+   switch (aspect) {
+   case VK_IMAGE_ASPECT_DEPTH_BIT:
+      isl_usage |= ISL_SURF_USAGE_DEPTH_BIT;
+      break;
+   case VK_IMAGE_ASPECT_STENCIL_BIT:
+      isl_usage |= ISL_SURF_USAGE_STENCIL_BIT;
+      break;
+   case VK_IMAGE_ASPECT_COLOR_BIT:
+      break;
+   default:
+      unreachable("bad VkImageAspect");
    }
 
    if (vk_usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
-      /* Meta implements transfers by sampling from the source image. */
+      /* blorp implements transfers by sampling from the source image. */
       isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
    }
 
-   if (vk_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
-      /* Meta implements transfers by rendering into the destination image. */
+   if (vk_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT &&
+       aspect == VK_IMAGE_ASPECT_COLOR_BIT) {
+      /* blorp implements transfers by rendering into the destination image.
+       * Only request this with color images, as we deal with depth/stencil
+       * formats differently. */
       isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
    }
 
@@ -108,7 +111,7 @@ add_surface(struct anv_image *image, struct anv_surface *surf)
 
    surf->offset = align_u32(image->size, surf->isl.alignment);
    image->size = surf->offset + surf->isl.size;
-   image->alignment = MAX(image->alignment, surf->isl.alignment);
+   image->alignment = MAX2(image->alignment, surf->isl.alignment);
 }
 
 /**
@@ -176,67 +179,67 @@ make_surface(const struct anv_device *dev,
 
    /* Add a HiZ surface to a depth buffer that will be used for rendering.
     */
-   if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT &&
-       (image->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
-
+   if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {
       /* Allow the user to control HiZ enabling. Disable by default on gen7
        * because resolves are not currently implemented pre-BDW.
        */
-      if (!env_var_as_boolean("INTEL_VK_HIZ", dev->info.gen >= 8)) {
+      if (!(image->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
+         /* It will never be used as an attachment, HiZ is pointless. */
+      } else if (image->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
+         /* From the 1.0.37 spec:
+          *
+          *    "An attachment used as an input attachment and depth/stencil
+          *    attachment must be in either VK_IMAGE_LAYOUT_GENERAL or
+          *    VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL."
+          *
+          * It will never have a layout of
+          * VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, so HiZ is
+          * currently pointless. If transfer operations learn to use the HiZ
+          * buffer, we can enable HiZ for VK_IMAGE_LAYOUT_GENERAL and support
+          * input attachments.
+          */
+         anv_finishme("Implement HiZ for input attachments");
+      } else if (!env_var_as_boolean("INTEL_VK_HIZ", dev->info.gen >= 8)) {
          anv_finishme("Implement gen7 HiZ");
       } else if (vk_info->mipLevels > 1) {
          anv_finishme("Test multi-LOD HiZ");
+      } else if (vk_info->arrayLayers > 1) {
+         anv_finishme("Implement multi-arrayLayer HiZ clears and resolves");
       } else if (dev->info.gen == 8 && vk_info->samples > 1) {
          anv_finishme("Test gen8 multisampled HiZ");
       } else {
+         assert(image->aux_surface.isl.size == 0);
          isl_surf_get_hiz_surf(&dev->isl_dev, &image->depth_surface.isl,
-                               &image->hiz_surface.isl);
-         add_surface(image, &image->hiz_surface);
+                               &image->aux_surface.isl);
+         add_surface(image, &image->aux_surface);
+         image->aux_usage = ISL_AUX_USAGE_HIZ;
       }
-   }
-
-   return VK_SUCCESS;
-}
-
-/**
- * Parameter @a format is required and overrides VkImageCreateInfo::format.
- */
-static VkImageUsageFlags
-anv_image_get_full_usage(const VkImageCreateInfo *info,
-                         VkImageAspectFlags aspects)
-{
-   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) {
-      /* 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 (aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
-         /* 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;
+   } else if (aspect == VK_IMAGE_ASPECT_COLOR_BIT && vk_info->samples == 1) {
+      if (!unlikely(INTEL_DEBUG & DEBUG_NO_RBC)) {
+         assert(image->aux_surface.isl.size == 0);
+         ok = isl_surf_get_ccs_surf(&dev->isl_dev, &anv_surf->isl,
+                                    &image->aux_surface.isl);
+         if (ok) {
+            add_surface(image, &image->aux_surface);
+
+            /* For images created without MUTABLE_FORMAT_BIT set, we know that
+             * they will always be used with the original format.  In
+             * particular, they will always be used with a format that
+             * supports color compression.  If it's never used as a storage
+             * image, then it will only be used through the sampler or the as
+             * a render target.  This means that it's safe to just leave
+             * compression on at all times for these formats.
+             */
+            if (!(vk_info->usage & VK_IMAGE_USAGE_STORAGE_BIT) &&
+                !(vk_info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) &&
+                isl_format_supports_ccs_e(&dev->info, format)) {
+               image->aux_usage = ISL_AUX_USAGE_CCS_E;
+            }
+         }
       }
    }
 
-   return usage;
+   return VK_SUCCESS;
 }
 
 VkResult
@@ -259,7 +262,7 @@ anv_image_create(VkDevice _device,
    anv_assert(pCreateInfo->extent.height > 0);
    anv_assert(pCreateInfo->extent.depth > 0);
 
-   image = anv_alloc2(&device->alloc, alloc, sizeof(*image), 8,
+   image = vk_alloc2(&device->alloc, alloc, sizeof(*image), 8,
                       VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
    if (!image)
       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
@@ -272,8 +275,9 @@ anv_image_create(VkDevice _device,
    image->levels = pCreateInfo->mipLevels;
    image->array_size = pCreateInfo->arrayLayers;
    image->samples = pCreateInfo->samples;
-   image->usage = anv_image_get_full_usage(pCreateInfo, image->aspects);
+   image->usage = pCreateInfo->usage;
    image->tiling = pCreateInfo->tiling;
+   image->aux_usage = ISL_AUX_USAGE_NONE;
 
    uint32_t b;
    for_each_bit(b, image->aspects) {
@@ -288,7 +292,7 @@ anv_image_create(VkDevice _device,
 
 fail:
    if (image)
-      anv_free2(&device->alloc, alloc, image);
+      vk_free2(&device->alloc, alloc, image);
 
    return r;
 }
@@ -312,8 +316,63 @@ anv_DestroyImage(VkDevice _device, VkImage _image,
                  const VkAllocationCallbacks *pAllocator)
 {
    ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_image, image, _image);
 
-   anv_free2(&device->alloc, pAllocator, anv_image_from_handle(_image));
+   if (!image)
+      return;
+
+   vk_free2(&device->alloc, pAllocator, image);
+}
+
+VkResult anv_BindImageMemory(
+    VkDevice                                    _device,
+    VkImage                                     _image,
+    VkDeviceMemory                              _memory,
+    VkDeviceSize                                memoryOffset)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_device_memory, mem, _memory);
+   ANV_FROM_HANDLE(anv_image, image, _image);
+
+   if (mem) {
+      image->bo = &mem->bo;
+      image->offset = memoryOffset;
+   } else {
+      image->bo = NULL;
+      image->offset = 0;
+   }
+
+   if (image->aux_surface.isl.size > 0) {
+
+      /* The offset and size must be a multiple of 4K or else the
+       * anv_gem_mmap call below will return NULL.
+       */
+      assert((image->offset + image->aux_surface.offset) % 4096 == 0);
+      assert(image->aux_surface.isl.size % 4096 == 0);
+
+      /* Auxiliary surfaces need to have their memory cleared to 0 before they
+       * can be used.  For CCS surfaces, this puts them in the "resolved"
+       * state so they can be used with CCS enabled before we ever touch it
+       * from the GPU.  For HiZ, we need something valid or else we may get
+       * GPU hangs on some hardware and 0 works fine.
+       */
+      void *map = anv_gem_mmap(device, image->bo->gem_handle,
+                               image->offset + image->aux_surface.offset,
+                               image->aux_surface.isl.size,
+                               device->info.has_llc ? 0 : I915_MMAP_WC);
+
+      /* If anv_gem_mmap returns NULL, it's likely that the kernel was
+       * not able to find space on the host to create a proper mapping.
+       */
+      if (map == NULL)
+         return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+      memset(map, 0, image->aux_surface.isl.size);
+
+      anv_gem_munmap(map, image->aux_surface.isl.size);
+   }
+
+   return VK_SUCCESS;
 }
 
 static void
@@ -364,14 +423,9 @@ void anv_GetImageSubresourceLayout(
 }
 
 static struct anv_state
-alloc_surface_state(struct anv_device *device,
-                    struct anv_cmd_buffer *cmd_buffer)
+alloc_surface_state(struct anv_device *device)
 {
-      if (cmd_buffer) {
-         return anv_cmd_buffer_alloc_surface_state(cmd_buffer);
-      } else {
-         return anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
-      }
+   return anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
 }
 
 static enum isl_channel_select
@@ -393,14 +447,22 @@ remap_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component,
    }
 }
 
-void
-anv_image_view_init(struct anv_image_view *iview,
-                    struct anv_device *device,
-                    const VkImageViewCreateInfopCreateInfo,
-                    struct anv_cmd_buffer *cmd_buffer,
-                    VkImageUsageFlags usage_mask)
+
+VkResult
+anv_CreateImageView(VkDevice _device,
+                    const VkImageViewCreateInfo *pCreateInfo,
+                    const VkAllocationCallbacks *pAllocator,
+                    VkImageView *pView)
 {
+   ANV_FROM_HANDLE(anv_device, device, _device);
    ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
+   struct anv_image_view *iview;
+
+   iview = vk_alloc2(&device->alloc, pAllocator, sizeof(*iview), 8,
+                      VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+   if (iview == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
    const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
 
    assert(range->layerCount > 0);
@@ -436,10 +498,7 @@ anv_image_view_init(struct anv_image_view *iview,
    struct anv_format format = anv_get_format(&device->info, pCreateInfo->format,
                                              range->aspectMask, image->tiling);
 
-   iview->base_layer = range->baseArrayLayer;
-   iview->base_mip = range->baseMipLevel;
-
-   struct isl_view isl_view = {
+   iview->isl = (struct isl_view) {
       .format = format.isl_format,
       .base_level = range->baseMipLevel,
       .levels = anv_get_levelCount(image, range),
@@ -463,74 +522,80 @@ anv_image_view_init(struct anv_image_view *iview,
       .depth  = anv_minify(image->extent.depth , range->baseMipLevel),
    };
 
-   isl_surf_usage_flags_t cube_usage;
+   if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_3D) {
+      iview->isl.base_array_layer = 0;
+      iview->isl.array_len = iview->extent.depth;
+   }
+
    if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE ||
        pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) {
-      cube_usage = ISL_SURF_USAGE_CUBE_BIT;
+      iview->isl.usage = ISL_SURF_USAGE_CUBE_BIT;
    } else {
-      cube_usage = 0;
+      iview->isl.usage = 0;
    }
 
-   if (image->usage & usage_mask & VK_IMAGE_USAGE_SAMPLED_BIT) {
-      iview->sampler_surface_state = alloc_surface_state(device, cmd_buffer);
-
-      isl_view.usage = cube_usage | ISL_SURF_USAGE_TEXTURE_BIT;
-      isl_surf_fill_state(&device->isl_dev,
-                          iview->sampler_surface_state.map,
-                          .surf = &surface->isl,
-                          .view = &isl_view,
-                          .mocs = device->default_mocs);
-
-      if (!device->info.has_llc)
-         anv_state_clflush(iview->sampler_surface_state);
-   } else {
-      iview->sampler_surface_state.alloc_size = 0;
+   /* If the HiZ buffer can be sampled from, set the constant clear color.
+    * If it cannot, disable the isl aux usage flag.
+    */
+   float red_clear_color = 0.0f;
+   enum isl_aux_usage surf_usage = image->aux_usage;
+   if (image->aux_usage == ISL_AUX_USAGE_HIZ) {
+      if (iview->aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT &&
+          anv_can_sample_with_hiz(device->info.gen, image->samples)) {
+         /* When a HiZ buffer is sampled on gen9+, ensure that
+          * the constant fast clear value is set in the surface state.
+          */
+         if (device->info.gen >= 9)
+            red_clear_color = ANV_HZ_FC_VAL;
+      } else {
+         surf_usage = ISL_AUX_USAGE_NONE;
+      }
    }
 
-   /* This is kind-of hackish.  It is possible, due to get_full_usage above,
-    * to get a surface state with a non-renderable format but with
-    * VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT.  This happens in particular for
-    * formats which aren't renderable but where we want to use Vulkan copy
-    * commands so VK_IMAGE_USAGE_TRANSFER_DST_BIT is set.  In the case of a
-    * copy, meta will use a format that we can render to, but most of the rest
-    * of the time, we don't want to create those surface states.  Once we
-    * start using blorp for copies, this problem will go away and we can
-    * remove a lot of hacks.
+   /* Input attachment surfaces for color are allocated and filled
+    * out at BeginRenderPass time because they need compression information.
+    * Compression is not yet enabled for depth textures and stencil doesn't
+    * allow compression so we can just use the texture surface state from the
+    * view.
     */
-   if ((image->usage & usage_mask & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) &&
-       isl_format_supports_rendering(&device->info, isl_view.format)) {
-      iview->color_rt_surface_state = alloc_surface_state(device, cmd_buffer);
+   if (image->usage & VK_IMAGE_USAGE_SAMPLED_BIT ||
+       (image->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT &&
+        !(iview->aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT))) {
+      iview->sampler_surface_state = alloc_surface_state(device);
 
-      isl_view.usage = cube_usage | ISL_SURF_USAGE_RENDER_TARGET_BIT;
+      struct isl_view view = iview->isl;
+      view.usage |= ISL_SURF_USAGE_TEXTURE_BIT;
       isl_surf_fill_state(&device->isl_dev,
-                          iview->color_rt_surface_state.map,
+                          iview->sampler_surface_state.map,
                           .surf = &surface->isl,
-                          .view = &isl_view,
+                          .view = &view,
+                          .clear_color.f32 = { red_clear_color,},
+                          .aux_surf = &image->aux_surface.isl,
+                          .aux_usage = surf_usage,
                           .mocs = device->default_mocs);
 
       if (!device->info.has_llc)
-         anv_state_clflush(iview->color_rt_surface_state);
+         anv_state_clflush(iview->sampler_surface_state);
    } else {
-      iview->color_rt_surface_state.alloc_size = 0;
+      iview->sampler_surface_state.alloc_size = 0;
    }
 
    /* NOTE: This one needs to go last since it may stomp isl_view.format */
-   if (image->usage & usage_mask & VK_IMAGE_USAGE_STORAGE_BIT) {
-      iview->storage_surface_state = alloc_surface_state(device, cmd_buffer);
+   if (image->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
+      iview->storage_surface_state = alloc_surface_state(device);
 
       if (isl_has_matching_typed_storage_image_format(&device->info,
                                                       format.isl_format)) {
-         isl_view.usage = cube_usage | ISL_SURF_USAGE_STORAGE_BIT;
-         isl_view.format = isl_lower_storage_image_format(&device->info,
-                                                          isl_view.format);
-         if (image->type == VK_IMAGE_TYPE_3D) {
-            isl_view.base_array_layer = 0;
-            isl_view.array_len = iview->extent.depth;
-         }
+         struct isl_view view = iview->isl;
+         view.usage |= ISL_SURF_USAGE_STORAGE_BIT;
+         view.format = isl_lower_storage_image_format(&device->info,
+                                                      format.isl_format);
          isl_surf_fill_state(&device->isl_dev,
                              iview->storage_surface_state.map,
                              .surf = &surface->isl,
-                             .view = &isl_view,
+                             .view = &view,
+                             .aux_surf = &image->aux_surface.isl,
+                             .aux_usage = surf_usage,
                              .mocs = device->default_mocs);
       } else {
          anv_fill_buffer_surface_state(device, iview->storage_surface_state,
@@ -541,32 +606,15 @@ anv_image_view_init(struct anv_image_view *iview,
 
       isl_surf_fill_image_param(&device->isl_dev,
                                 &iview->storage_image_param,
-                                &surface->isl, &isl_view);
+                                &surface->isl, &iview->isl);
 
       if (!device->info.has_llc)
          anv_state_clflush(iview->storage_surface_state);
    } else {
       iview->storage_surface_state.alloc_size = 0;
    }
-}
 
-VkResult
-anv_CreateImageView(VkDevice _device,
-                    const VkImageViewCreateInfo *pCreateInfo,
-                    const VkAllocationCallbacks *pAllocator,
-                    VkImageView *pView)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   struct anv_image_view *view;
-
-   view = anv_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
-                     VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
-   if (view == NULL)
-      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
-
-   anv_image_view_init(view, device, pCreateInfo, NULL, ~0);
-
-   *pView = anv_image_view_to_handle(view);
+   *pView = anv_image_view_to_handle(iview);
 
    return VK_SUCCESS;
 }
@@ -578,10 +626,8 @@ anv_DestroyImageView(VkDevice _device, VkImageView _iview,
    ANV_FROM_HANDLE(anv_device, device, _device);
    ANV_FROM_HANDLE(anv_image_view, iview, _iview);
 
-   if (iview->color_rt_surface_state.alloc_size > 0) {
-      anv_state_pool_free(&device->surface_state_pool,
-                          iview->color_rt_surface_state);
-   }
+   if (!iview)
+      return;
 
    if (iview->sampler_surface_state.alloc_size > 0) {
       anv_state_pool_free(&device->surface_state_pool,
@@ -593,16 +639,24 @@ anv_DestroyImageView(VkDevice _device, VkImageView _iview,
                           iview->storage_surface_state);
    }
 
-   anv_free2(&device->alloc, pAllocator, iview);
+   vk_free2(&device->alloc, pAllocator, iview);
 }
 
 
-void anv_buffer_view_init(struct anv_buffer_view *view,
-                          struct anv_device *device,
-                          const VkBufferViewCreateInfo* pCreateInfo,
-                          struct anv_cmd_buffer *cmd_buffer)
+VkResult
+anv_CreateBufferView(VkDevice _device,
+                     const VkBufferViewCreateInfo *pCreateInfo,
+                     const VkAllocationCallbacks *pAllocator,
+                     VkBufferView *pView)
 {
+   ANV_FROM_HANDLE(anv_device, device, _device);
    ANV_FROM_HANDLE(anv_buffer, buffer, pCreateInfo->buffer);
+   struct anv_buffer_view *view;
+
+   view = vk_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
+                     VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+   if (!view)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
    /* TODO: Handle the format swizzle? */
 
@@ -617,7 +671,7 @@ void anv_buffer_view_init(struct anv_buffer_view *view,
    view->range = align_down_npot_u32(view->range, format_bs);
 
    if (buffer->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) {
-      view->surface_state = alloc_surface_state(device, cmd_buffer);
+      view->surface_state = alloc_surface_state(device);
 
       anv_fill_buffer_surface_state(device, view->surface_state,
                                     view->format,
@@ -627,7 +681,7 @@ void anv_buffer_view_init(struct anv_buffer_view *view,
    }
 
    if (buffer->usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) {
-      view->storage_surface_state = alloc_surface_state(device, cmd_buffer);
+      view->storage_surface_state = alloc_surface_state(device);
 
       enum isl_format storage_format =
          isl_has_matching_typed_storage_image_format(&device->info,
@@ -647,23 +701,6 @@ void anv_buffer_view_init(struct anv_buffer_view *view,
    } else {
       view->storage_surface_state = (struct anv_state){ 0 };
    }
-}
-
-VkResult
-anv_CreateBufferView(VkDevice _device,
-                     const VkBufferViewCreateInfo *pCreateInfo,
-                     const VkAllocationCallbacks *pAllocator,
-                     VkBufferView *pView)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   struct anv_buffer_view *view;
-
-   view = anv_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
-                     VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
-   if (!view)
-      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
-
-   anv_buffer_view_init(view, device, pCreateInfo, NULL);
 
    *pView = anv_buffer_view_to_handle(view);
 
@@ -677,6 +714,9 @@ anv_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
    ANV_FROM_HANDLE(anv_device, device, _device);
    ANV_FROM_HANDLE(anv_buffer_view, view, bufferView);
 
+   if (!view)
+      return;
+
    if (view->surface_state.alloc_size > 0)
       anv_state_pool_free(&device->surface_state_pool,
                           view->surface_state);
@@ -685,7 +725,7 @@ anv_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
       anv_state_pool_free(&device->surface_state_pool,
                           view->storage_surface_state);
 
-   anv_free2(&device->alloc, pAllocator, view);
+   vk_free2(&device->alloc, pAllocator, view);
 }
 
 const struct anv_surface *
@@ -694,20 +734,8 @@ anv_image_get_surface_for_aspect_mask(const struct anv_image *image,
 {
    switch (aspect_mask) {
    case VK_IMAGE_ASPECT_COLOR_BIT:
-      /* Dragons will eat you.
-       *
-       * Meta attaches all destination surfaces as color render targets. Guess
-       * what surface the Meta Dragons really want.
-       */
-      if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
-         return &image->depth_surface;
-      } else if (image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
-         return &image->stencil_surface;
-      } else {
-         assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
-         return &image->color_surface;
-      }
-      break;
+      assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
+      return &image->color_surface;
    case VK_IMAGE_ASPECT_DEPTH_BIT:
       assert(image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT);
       return &image->depth_surface;