[Mesa-dev] [PATCH 05/22] anv/image: Append CCS/MCS with a clear value buffer

Nanley Chery nanleychery at gmail.com
Thu Apr 27 18:32:04 UTC 2017


Signed-off-by: Nanley Chery <nanley.g.chery at intel.com>
---
 src/intel/vulkan/anv_image.c | 67 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
index cf34dbe3b0..8d946e8e93 100644
--- a/src/intel/vulkan/anv_image.c
+++ b/src/intel/vulkan/anv_image.c
@@ -114,6 +114,71 @@ add_surface(struct anv_image *image, struct anv_surface *surf)
    image->alignment = MAX2(image->alignment, surf->isl.alignment);
 }
 
+
+/**
+ * For color buffers that have an auxiliary buffer enabled, there is an
+ * additional buffer that keeps track of fast clear values. Using this
+ * buffer allows us to access image subresources while being aware of their
+ * fast clear values in non-trivial cases.
+ *
+ * The clear values in this buffer are updated when a fast clear is performed
+ * on a subresource. Two synchronization operations can be performed in order
+ * for the next memory access to use the fast-clear value:
+ *   a. Copy the value from the buffer to the surface state object used for
+ *      reading (if different).
+ *   b. Do (a) onto a surface state object and use it to resolve the
+ *      subresource.
+ *
+ * The synchronization approach currently taken is as follows. We place
+ * resolves in the hands of the user via layout transitions. We also sometimes
+ * skip resolves when a clear value predetermined to be the default in other
+ * surface state objects is used in a fast clear.
+ *
+ * We fast-clear (and so cause things to get temporarily unsynchronized)
+ * whenever the hardware allows except for two cases: when in the GENERAL
+ * layout and when clearing a proper subset of a layered image. The exception
+ * is made for the former because a layout transition isn't required before
+ * sampling from an image in that layout. The exception is made for the latter
+ * because a layout transition isn't required between a render pass that
+ * renders to a proper subset of a layered image and another render pass that
+ * renders to every layer in the layered image.
+ */
+static void
+add_clear_value_buffer(struct anv_image * const image,
+                       const struct anv_device * const device)
+{
+   assert(image && device);
+
+   /* Only color auxiliary buffers have use for this. */
+   assert(anv_image_has_color_aux(image));
+
+   /* The offset to the buffer of clear values must be dword-aligned for GPU
+    * memcpy operations. It is located immediately after the auxiliary surface.
+    */
+
+   /* Tiled images are guaranteed to be 4K aligned, so the image alignment
+    * should also be dword-aligned.
+    */
+   assert(image->alignment % 4 == 0);
+
+   /* Auxiliary buffers should be a multiple of 4K, so the start of the clear
+    * values buffer should already be dword-aligned.
+    */
+   assert(image->aux_surface.isl.size % 4 == 0);
+
+   /* This surface should be at the very end of the image. */
+   assert(image->size ==
+          image->aux_surface.offset + image->aux_surface.isl.size);
+
+   /* Entire surface state objects are stored instead of just clear colors for
+    * two reasons:
+    *   1. Pre-SKL, we must compute some state fields that lie in the same
+    *      dword as the clear value.
+    *   2. Storing either set of objects requires less than a page of memory.
+    */
+   image->size += device->isl_dev.ss.size * anv_color_aux_levels(image);
+}
+
 /**
  * Initialize the anv_image::*_surface selected by \a aspect. Then update the
  * image's memory requirements (that is, the image's size and alignment).
@@ -213,6 +278,7 @@ make_surface(const struct anv_device *dev,
                                     &image->aux_surface.isl);
          if (ok) {
             add_surface(image, &image->aux_surface);
+            add_clear_value_buffer(image, dev);
 
             /* For images created without MUTABLE_FORMAT_BIT set, we know that
              * they will always be used with the original format.  In
@@ -236,6 +302,7 @@ make_surface(const struct anv_device *dev,
                                  &image->aux_surface.isl);
       if (ok) {
          add_surface(image, &image->aux_surface);
+         add_clear_value_buffer(image, dev);
          image->aux_usage = ISL_AUX_USAGE_MCS;
       }
    }
-- 
2.12.2



More information about the mesa-dev mailing list