anv/pipeline: Delete out-of-bounds fragment shader outputs
[mesa.git] / src / vulkan / anv_image.c
index 74f1eca48f257b11fa173ce41e9daf1498e37775..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(VkImageUsageFlags vk_usage,
                       VkImageAspectFlags aspect)
 {
-   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_usage & VK_IMAGE_USAGE_SAMPLED_BIT)
-      isl_flags |= ISL_SURF_USAGE_TEXTURE_BIT;
+      isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
 
    if (vk_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)
-      isl_flags |= ISL_SURF_USAGE_TEXTURE_BIT;
+      isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
 
    if (vk_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
-      isl_flags |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
+      isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
 
    if (vk_usage & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
-      isl_flags |= ISL_SURF_USAGE_CUBE_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_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_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_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;
 }
 
 /**
@@ -125,13 +124,30 @@ 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,
@@ -152,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;
 
@@ -169,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;
@@ -187,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);
@@ -207,14 +239,14 @@ 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)