gallium: add separate PIPE_CAP_INT64_DIVMOD
[mesa.git] / src / intel / vulkan / anv_image.c
index 4b730aec353fc666c450f00d4eafbe0942166e97..e59ef4dbb6759ebe5d7786bc7b5e282e5f5bbc31 100644 (file)
@@ -75,8 +75,11 @@ choose_isl_surf_usage(VkImageUsageFlags vk_usage,
       isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
    }
 
-   if (vk_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
-      /* blorp 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;
    }
 
@@ -176,22 +179,63 @@ 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;
+      }
+   } 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;
+            }
+         }
       }
    }
 
@@ -233,6 +277,7 @@ anv_image_create(VkDevice _device,
    image->samples = pCreateInfo->samples;
    image->usage = pCreateInfo->usage;
    image->tiling = pCreateInfo->tiling;
+   image->aux_usage = ISL_AUX_USAGE_NONE;
 
    uint32_t b;
    for_each_bit(b, image->aspects) {
@@ -297,21 +342,23 @@ VkResult anv_BindImageMemory(
       image->offset = 0;
    }
 
-   if (anv_image_has_hiz(image)) {
+   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->hiz_surface.offset) % 4096 == 0);
-      assert(image->hiz_surface.isl.size % 4096 == 0);
-
-      /* HiZ surfaces need to have their memory cleared to 0 before they
-       * can be used.  If we let it have garbage data, it can cause GPU
-       * hangs on some hardware.
+      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->hiz_surface.offset,
-                               image->hiz_surface.isl.size,
+                               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
@@ -320,9 +367,9 @@ VkResult anv_BindImageMemory(
       if (map == NULL)
          return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
-      memset(map, 0, image->hiz_surface.isl.size);
+      memset(map, 0, image->aux_surface.isl.size);
 
-      anv_gem_munmap(map, image->hiz_surface.isl.size);
+      anv_gem_munmap(map, image->aux_surface.isl.size);
    }
 
    return VK_SUCCESS;
@@ -475,7 +522,7 @@ anv_CreateImageView(VkDevice _device,
       .depth  = anv_minify(image->extent.depth , range->baseMipLevel),
    };
 
-   if (image->type == VK_IMAGE_TYPE_3D) {
+   if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_3D) {
       iview->isl.base_array_layer = 0;
       iview->isl.array_len = iview->extent.depth;
    }
@@ -487,7 +534,33 @@ anv_CreateImageView(VkDevice _device,
       iview->isl.usage = 0;
    }
 
-   if (image->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
+   /* 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;
+      }
+   }
+
+   /* 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 & 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);
 
       struct isl_view view = iview->isl;
@@ -496,6 +569,9 @@ anv_CreateImageView(VkDevice _device,
                           iview->sampler_surface_state.map,
                           .surf = &surface->isl,
                           .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)
@@ -518,6 +594,8 @@ anv_CreateImageView(VkDevice _device,
                              iview->storage_surface_state.map,
                              .surf = &surface->isl,
                              .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,