[Mesa-dev] [PATCH 12/13] anv: Add some basic infrastructure for aux surfaces

Jason Ekstrand jason at jlekstrand.net
Sun Sep 25 16:59:11 UTC 2016


This adds an aux_surface member to anv_image as well as the various bits of
plumbing required to initialize them in BindImageMemory, keep track of the
aux_usage, and add the surface state relocations.

Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
---
 src/intel/vulkan/anv_cmd_buffer.c | 28 +++++++++++++++++++++++++---
 src/intel/vulkan/anv_device.c     |  3 +++
 src/intel/vulkan/anv_image.c      | 19 ++++++++++++++++++-
 src/intel/vulkan/anv_private.h    |  6 ++++++
 4 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c
index 34109c9..e5ab7d0 100644
--- a/src/intel/vulkan/anv_cmd_buffer.c
+++ b/src/intel/vulkan/anv_cmd_buffer.c
@@ -693,6 +693,7 @@ add_surface_state_reloc(struct anv_cmd_buffer *cmd_buffer,
 static void
 add_image_view_relocs(struct anv_cmd_buffer *cmd_buffer,
                       const struct anv_image_view *iview,
+                      enum isl_aux_usage aux_usage,
                       struct anv_state state)
 {
    const struct isl_device *isl_dev = &cmd_buffer->device->isl_dev;
@@ -700,6 +701,22 @@ add_image_view_relocs(struct anv_cmd_buffer *cmd_buffer,
    anv_reloc_list_add(&cmd_buffer->surface_relocs, &cmd_buffer->pool->alloc,
                       state.offset + isl_dev->ss.addr_offset,
                       iview->bo, iview->offset);
+
+   if (aux_usage != ISL_AUX_USAGE_NONE) {
+      uint32_t aux_offset = iview->offset + iview->image->aux_surface.offset;
+
+      /* On gen7 and prior, the bottom 12 bits of the MCS base address are
+       * used to store other information.  This should be ok, however, because
+       * surface buffer addresses are always 4K page alinged.
+       */
+      assert((aux_offset & 0xfff) == 0);
+      uint32_t *aux_addr_dw = state.map + isl_dev->ss.aux_addr_offset;
+      aux_offset += *aux_addr_dw & 0xfff;
+
+      anv_reloc_list_add(&cmd_buffer->surface_relocs, &cmd_buffer->pool->alloc,
+                         state.offset + isl_dev->ss.aux_addr_offset,
+                         iview->bo, aux_offset);
+   }
 }
 
 enum isl_format
@@ -827,7 +844,8 @@ anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
             surface_state.offset += fb_att->rt_state_offset;
             surface_state.map += fb_att->rt_state_offset;
 
-            add_image_view_relocs(cmd_buffer, fb_att->view, surface_state);
+            add_image_view_relocs(cmd_buffer, fb_att->view, fb_att->aux_usage,
+                                  surface_state);
          } else {
             /* Null render target */
             struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
@@ -854,13 +872,17 @@ anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
       case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
          surface_state = desc->image_view->sampler_surface_state;
          assert(surface_state.alloc_size);
-         add_image_view_relocs(cmd_buffer, desc->image_view, surface_state);
+         add_image_view_relocs(cmd_buffer, desc->image_view,
+                               desc->image_view->image->aux_usage,
+                               surface_state);
          break;
 
       case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
          surface_state = desc->image_view->storage_surface_state;
          assert(surface_state.alloc_size);
-         add_image_view_relocs(cmd_buffer, desc->image_view, surface_state);
+         add_image_view_relocs(cmd_buffer, desc->image_view,
+                               desc->image_view->image->aux_usage,
+                               surface_state);
 
          struct brw_image_param *image_param =
             &cmd_buffer->state.push_constants[stage]->images[image++];
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index 5780894..3d4b783 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -1789,6 +1789,7 @@ VkResult anv_CreateFramebuffer(
       ANV_FROM_HANDLE(anv_image_view, iview, pCreateInfo->pAttachments[i]);
 
       framebuffer->attachments[i].view = iview;
+      framebuffer->attachments[i].aux_usage = iview->image->aux_usage;
       framebuffer->attachments[i].rt_state_offset = -1;
 
       if (iview->image->aspects & VK_IMAGE_ASPECT_COLOR_BIT)
@@ -1812,6 +1813,8 @@ VkResult anv_CreateFramebuffer(
                              framebuffer->surface_states.map + offset,
                              .surf = &iview->image->color_surface.isl,
                              .view = &isl_view,
+                             .aux_surf = &iview->image->aux_surface.isl,
+                             .aux_usage = fb_att->aux_usage,
                              .mocs = device->default_mocs);
       }
    }
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
index d814411..405b923 100644
--- a/src/intel/vulkan/anv_image.c
+++ b/src/intel/vulkan/anv_image.c
@@ -248,6 +248,7 @@ anv_image_create(VkDevice _device,
    image->samples = pCreateInfo->samples;
    image->usage = anv_image_get_full_usage(pCreateInfo, image->aspects);
    image->tiling = pCreateInfo->tiling;
+   image->aux_usage = ISL_AUX_USAGE_NONE;
 
    uint32_t b;
    for_each_bit(b, image->aspects) {
@@ -291,17 +292,33 @@ anv_DestroyImage(VkDevice _device, VkImage _image,
 }
 
 VkResult anv_BindImageMemory(
-    VkDevice                                    device,
+    VkDevice                                    _device,
     VkImage                                     _image,
     VkDeviceMemory                              _memory,
     VkDeviceSize                                memoryOffset)
 {
+   ANV_FROM_HANDLE(anv_device, device, _device);
    ANV_FROM_HANDLE(anv_device_memory, mem, _memory);
    ANV_FROM_HANDLE(anv_image, image, _image);
 
    if (mem) {
       image->bo = &mem->bo;
       image->offset = memoryOffset;
+
+      if (image->aux_surface.isl.size > 0) {
+         /* Auxiliary surfaces need to have their memory initialized before
+          * they can be used.  HiZ is particularly bad, where garbage data can
+          * lead go GPU hangs.
+          */
+         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);
+
+         memset(map, 0, image->aux_surface.isl.size);
+
+         anv_gem_munmap(map, image->aux_surface.isl.size);
+      }
    } else {
       image->bo = NULL;
       image->offset = 0;
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 4046c6c..5c24c37 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -1700,6 +1700,11 @@ struct anv_image {
          struct anv_surface stencil_surface;
       };
    };
+
+   /** The usage of the aux surface when not in a renderpass. */
+   enum isl_aux_usage aux_usage;
+
+   struct anv_surface aux_surface;
 };
 
 static inline uint32_t
@@ -1835,6 +1840,7 @@ struct anv_sampler {
 
 struct anv_framebuffer_attachment {
    struct anv_image_view *                      view;
+   enum isl_aux_usage                           aux_usage;
    int16_t                                      rt_state_offset;
 };
 
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list