anv/pipeline: Delete out-of-bounds fragment shader outputs
[mesa.git] / src / vulkan / anv_image.c
index 2ed654feee2e6a6d1fa51c26790d5f05d1be1594..0a412a3f8c668e40ab62620d7e77edef57ba6a7b 100644 (file)
 #include "anv_private.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;
 }
 
 /**
@@ -126,19 +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,
                                    vk_info->tiling, NULL),
-      .width = vk_info->extent.width,
-      .height = vk_info->extent.height,
-      .depth = vk_info->extent.depth,
+      .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
@@ -153,8 +168,12 @@ 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;
 
@@ -170,10 +189,21 @@ anv_image_get_full_usage(const VkImageCreateInfo *info)
    }
 
    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;
@@ -188,6 +218,7 @@ 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);
@@ -208,20 +239,20 @@ anv_image_create(VkDevice _device,
    image->type = pCreateInfo->imageType;
    image->extent = pCreateInfo->extent;
    image->vk_format = pCreateInfo->format;
-   image->format = anv_format_for_vk_format(pCreateInfo->format);
+   image->format = format;
    image->levels = pCreateInfo->mipLevels;
    image->array_size = pCreateInfo->arrayLayers;
    image->samples = pCreateInfo->samples;
-   image->usage = anv_image_get_full_usage(pCreateInfo);
+   image->usage = anv_image_get_full_usage(pCreateInfo, format);
    image->tiling = pCreateInfo->tiling;
 
-   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)
@@ -368,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);
@@ -378,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);
       }
@@ -730,9 +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) {
+      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;
@@ -741,13 +772,13 @@ 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) {
+      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:
           *
@@ -760,7 +791,7 @@ anv_image_get_surface_for_aspect_mask(struct anv_image *image, VkImageAspectFlag
           * stencil surfaces from the underlying surface.
           */
          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;