[Mesa-dev] [PATCH 09/24] anv/image: Initialize the clear values buffer

Nanley Chery nanleychery at gmail.com
Thu May 11 19:05:16 UTC 2017


Signed-off-by: Nanley Chery <nanley.g.chery at intel.com>
---
 src/intel/vulkan/anv_image.c   | 71 ++++++++++++++++++++++++++++++++++++------
 src/intel/vulkan/anv_private.h |  5 +++
 2 files changed, 67 insertions(+), 9 deletions(-)

diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
index 6b6cc324b3..eefbe2f990 100644
--- a/src/intel/vulkan/anv_image.c
+++ b/src/intel/vulkan/anv_image.c
@@ -180,6 +180,37 @@ add_clear_value_buffer(struct anv_image * const image,
    image->size += device->isl_dev.ss.size * anv_color_aux_levels(image);
 }
 
+/* Populates a buffer with a surface state object that can be used for
+ * resolving the specified subresource of a CCS buffer.
+ */
+void
+anv_fill_ccs_resolve_ss(const struct anv_device * const device,
+                        void * const data, const struct anv_image * const image,
+                        const uint8_t level, const uint32_t layer)
+{
+   assert(device && image && data);
+
+   /* The image subresource must have a color auxiliary buffer. */
+   assert(level < anv_color_aux_levels(image));
+   assert(layer < anv_color_aux_layers(image, level));
+
+   isl_surf_fill_state(&device->isl_dev, data,
+                       .surf = &image->color_surface.isl,
+                       .view = &(struct isl_view) {
+                           .usage = ISL_SURF_USAGE_RENDER_TARGET_BIT,
+                           .format = image->color_surface.isl.format,
+                           .swizzle = ISL_SWIZZLE_IDENTITY,
+                           .base_level = level,
+                           .levels = 1,
+                           .base_array_layer = layer,
+                           .array_len = 1,
+                        },
+                       .aux_surf = &image->aux_surface.isl,
+                       .aux_usage = image->aux_usage == ISL_AUX_USAGE_NONE ?
+                                    ISL_AUX_USAGE_CCS_D : image->aux_usage,
+                       .mocs = device->default_mocs);
+}
+
 /**
  * Initialize the anv_image::*_surface selected by \a aspect. Then update the
  * image's memory requirements (that is, the image's size and alignment).
@@ -412,6 +443,9 @@ VkResult anv_BindImageMemory(
    image->bo = mem->bo;
    image->offset = memoryOffset;
 
+   /* The data after the main surface must be initialized for various
+    * reasons.
+    */
    if (image->aux_surface.isl.size > 0) {
 
       /* The offset must be a multiple of 4K or else the anv_gem_mmap call
@@ -419,23 +453,42 @@ VkResult anv_BindImageMemory(
        */
       assert((image->offset + image->aux_surface.offset) % 4096 == 0);
 
+      const uint32_t image_map_size = image->size - image->aux_surface.offset;
+      void * const map = anv_gem_mmap(device, image->bo->gem_handle,
+                                      image->offset + image->aux_surface.offset,
+                                      image_map_size,
+                                      device->info.has_llc ? 0 : I915_MMAP_WC);
+
+      if (map == MAP_FAILED)
+         return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
       /* 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 (map == MAP_FAILED)
-         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);
+      /* For color auxiliary surfaces, the clear values buffer must be
+       * initialized. This is because a render pass attachment's loadOp may be
+       * LOAD_OP_LOAD, triggering a GPU memcpy from the clear values buffer
+       * into the surface state object. Pre-SKL, the dword containing the clear
+       * values also contains other fields, so we need to initialize those
+       * fields to match the values for a color attachment. On SKL+, the MCS
+       * surface state only allows 1/0 clear colors. Using the fill function
+       * for a CCS resolve state also gives the desired result for MCS images.
+       */
+      if (image->aspects == VK_IMAGE_ASPECT_COLOR_BIT &&
+          (device->info.gen <= 8 || image->samples > 1)) {
+         for (uint8_t lod = 0; lod < anv_color_aux_levels(image); ++lod) {
+            anv_fill_ccs_resolve_ss(device, map + image->aux_surface.isl.size +
+                                    device->isl_dev.ss.size * lod,
+                                    image, lod, 0);
+         }
+      }
+
+      anv_gem_munmap(map, image_map_size);
    }
 
    return VK_SUCCESS;
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 9bbb8f7221..b0752d286d 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -2096,6 +2096,11 @@ anv_color_aux_layers(const struct anv_image * const image,
    }
 }
 
+void
+anv_fill_ccs_resolve_ss(const struct anv_device * const device,
+                        void * const data, const struct anv_image * const image,
+                        const uint8_t level, const uint32_t layer);
+
 /* Returns true if a HiZ-enabled depth buffer can be sampled from. */
 static inline bool
 anv_can_sample_with_hiz(const struct gen_device_info * const devinfo,
-- 
2.12.2



More information about the mesa-dev mailing list