[Mesa-dev] [PATCH 10/13] anv: Create render target surface states in CreateFramebuffer

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


Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
---
 src/intel/vulkan/anv_blorp.c      |  4 ++--
 src/intel/vulkan/anv_cmd_buffer.c | 14 ++++++++------
 src/intel/vulkan/anv_device.c     | 38 +++++++++++++++++++++++++++++++++++---
 src/intel/vulkan/anv_dump.c       |  2 +-
 src/intel/vulkan/anv_image.c      | 33 ---------------------------------
 src/intel/vulkan/anv_meta_clear.c |  4 ++--
 src/intel/vulkan/anv_private.h    | 12 ++++++++----
 7 files changed, 56 insertions(+), 51 deletions(-)

diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c
index 9589510..5cc19eb 100644
--- a/src/intel/vulkan/anv_blorp.c
+++ b/src/intel/vulkan/anv_blorp.c
@@ -911,8 +911,8 @@ anv_cmd_buffer_resolve_subpass(struct anv_cmd_buffer *cmd_buffer)
       if (dst_att == VK_ATTACHMENT_UNUSED)
          continue;
 
-      struct anv_image_view *src_iview = fb->attachments[src_att];
-      struct anv_image_view *dst_iview = fb->attachments[dst_att];
+      struct anv_image_view *src_iview = fb->attachments[src_att].view;
+      struct anv_image_view *dst_iview = fb->attachments[dst_att].view;
 
       const VkRect2D render_area = cmd_buffer->state.render_area;
 
diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c
index 3d627d0..34109c9 100644
--- a/src/intel/vulkan/anv_cmd_buffer.c
+++ b/src/intel/vulkan/anv_cmd_buffer.c
@@ -820,12 +820,14 @@ anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
          assert(stage == MESA_SHADER_FRAGMENT);
          assert(binding->binding == 0);
          if (binding->index < subpass->color_count) {
-            const struct anv_image_view *iview =
-               fb->attachments[subpass->color_attachments[binding->index]];
+            const struct anv_framebuffer_attachment *fb_att =
+               &fb->attachments[subpass->color_attachments[binding->index]];
 
-            assert(iview->color_rt_surface_state.alloc_size);
-            surface_state = iview->color_rt_surface_state;
-            add_image_view_relocs(cmd_buffer, iview, surface_state);
+            surface_state = fb->surface_states;
+            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);
          } else {
             /* Null render target */
             struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
@@ -1292,7 +1294,7 @@ anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer *cmd_buffer)
       return NULL;
 
    const struct anv_image_view *iview =
-      fb->attachments[subpass->depth_stencil_attachment];
+      fb->attachments[subpass->depth_stencil_attachment].view;
 
    assert(iview->aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT |
                                 VK_IMAGE_ASPECT_STENCIL_BIT));
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index f786ebe..cda7324 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -1797,18 +1797,48 @@ VkResult anv_CreateFramebuffer(
    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
 
    size_t size = sizeof(*framebuffer) +
-                 sizeof(struct anv_image_view *) * pCreateInfo->attachmentCount;
+      sizeof(*framebuffer->attachments) * pCreateInfo->attachmentCount;
    framebuffer = anv_alloc2(&device->alloc, pAllocator, size, 8,
                             VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
    if (framebuffer == NULL)
       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
    framebuffer->attachment_count = pCreateInfo->attachmentCount;
+   unsigned color_count = 0;
    for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
-      VkImageView _iview = pCreateInfo->pAttachments[i];
-      framebuffer->attachments[i] = anv_image_view_from_handle(_iview);
+      ANV_FROM_HANDLE(anv_image_view, iview, pCreateInfo->pAttachments[i]);
+
+      framebuffer->attachments[i].view = iview;
+      framebuffer->attachments[i].rt_state_offset = -1;
+
+      if (iview->image->aspects & VK_IMAGE_ASPECT_COLOR_BIT)
+         color_count++;
    }
 
+   framebuffer->surface_states =
+      anv_state_pool_alloc(&device->surface_state_pool,
+                           device->isl_dev.ss.align * color_count,
+                           device->isl_dev.ss.align);
+   unsigned color_idx = 0;
+   for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
+      struct anv_image_view *iview = framebuffer->attachments[i].view;
+      if (iview->image->aspects & VK_IMAGE_ASPECT_COLOR_BIT) {
+         const uint16_t offset = (color_idx++) * device->isl_dev.ss.align;
+         framebuffer->attachments[i].rt_state_offset = offset;
+
+         struct isl_view isl_view = iview->isl;
+         isl_view.usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
+         isl_surf_fill_state(&device->isl_dev,
+                             framebuffer->surface_states.map + offset,
+                             .surf = &iview->image->color_surface.isl,
+                             .view = &isl_view,
+                             .mocs = device->default_mocs);
+      }
+   }
+
+   if (device->info.has_llc)
+      anv_state_clflush(framebuffer->surface_states);
+
    framebuffer->width = pCreateInfo->width;
    framebuffer->height = pCreateInfo->height;
    framebuffer->layers = pCreateInfo->layers;
@@ -1826,5 +1856,7 @@ void anv_DestroyFramebuffer(
    ANV_FROM_HANDLE(anv_device, device, _device);
    ANV_FROM_HANDLE(anv_framebuffer, fb, _fb);
 
+   anv_state_pool_free(&device->surface_state_pool, fb->surface_states);
+
    anv_free2(&device->alloc, pAllocator, fb);
 }
diff --git a/src/intel/vulkan/anv_dump.c b/src/intel/vulkan/anv_dump.c
index ed1b575..ea35d3f 100644
--- a/src/intel/vulkan/anv_dump.c
+++ b/src/intel/vulkan/anv_dump.c
@@ -408,7 +408,7 @@ anv_dump_add_framebuffer(struct anv_cmd_buffer *cmd_buffer,
    unsigned dump_idx = dump_count++;
 
    for (unsigned i = 0; i < fb->attachment_count; i++) {
-      struct anv_image_view *iview = fb->attachments[i];
+      struct anv_image_view *iview = fb->attachments[i].view;
 
       uint32_t b;
       for_each_bit(b, iview->image->aspects) {
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
index fd8956b..1068cd4 100644
--- a/src/intel/vulkan/anv_image.c
+++ b/src/intel/vulkan/anv_image.c
@@ -470,34 +470,6 @@ anv_image_view_init(struct anv_image_view *iview,
       iview->sampler_surface_state.alloc_size = 0;
    }
 
-   /* This is kind-of hackish.  It is possible, due to get_full_usage above,
-    * to get a surface state with a non-renderable format but with
-    * VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT.  This happens in particular for
-    * formats which aren't renderable but where we want to use Vulkan copy
-    * commands so VK_IMAGE_USAGE_TRANSFER_DST_BIT is set.  In the case of a
-    * copy, meta will use a format that we can render to, but most of the rest
-    * of the time, we don't want to create those surface states.  Once we
-    * start using blorp for copies, this problem will go away and we can
-    * remove a lot of hacks.
-    */
-   if ((image->usage & usage_mask & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) &&
-       isl_format_supports_rendering(&device->info, format.isl_format)) {
-      iview->color_rt_surface_state = alloc_surface_state(device, cmd_buffer);
-
-      struct isl_view view = iview->isl;
-      view.usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
-      isl_surf_fill_state(&device->isl_dev,
-                          iview->color_rt_surface_state.map,
-                          .surf = &surface->isl,
-                          .view = &view,
-                          .mocs = device->default_mocs);
-
-      if (!device->info.has_llc)
-         anv_state_clflush(iview->color_rt_surface_state);
-   } else {
-      iview->color_rt_surface_state.alloc_size = 0;
-   }
-
    /* NOTE: This one needs to go last since it may stomp isl_view.format */
    if (image->usage & usage_mask & VK_IMAGE_USAGE_STORAGE_BIT) {
       iview->storage_surface_state = alloc_surface_state(device, cmd_buffer);
@@ -559,11 +531,6 @@ anv_DestroyImageView(VkDevice _device, VkImageView _iview,
    ANV_FROM_HANDLE(anv_device, device, _device);
    ANV_FROM_HANDLE(anv_image_view, iview, _iview);
 
-   if (iview->color_rt_surface_state.alloc_size > 0) {
-      anv_state_pool_free(&device->surface_state_pool,
-                          iview->color_rt_surface_state);
-   }
-
    if (iview->sampler_surface_state.alloc_size > 0) {
       anv_state_pool_free(&device->surface_state_pool,
                           iview->sampler_surface_state);
diff --git a/src/intel/vulkan/anv_meta_clear.c b/src/intel/vulkan/anv_meta_clear.c
index 11b471f..4fcec06 100644
--- a/src/intel/vulkan/anv_meta_clear.c
+++ b/src/intel/vulkan/anv_meta_clear.c
@@ -346,7 +346,7 @@ emit_color_clear(struct anv_cmd_buffer *cmd_buffer,
    const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
    const uint32_t subpass_att = clear_att->colorAttachment;
    const uint32_t pass_att = subpass->color_attachments[subpass_att];
-   const struct anv_image_view *iview = fb->attachments[pass_att];
+   const struct anv_image_view *iview = fb->attachments[pass_att].view;
    const uint32_t samples = iview->image->samples;
    const uint32_t samples_log2 = ffs(samples) - 1;
    struct anv_pipeline *pipeline =
@@ -513,7 +513,7 @@ emit_depthstencil_clear(struct anv_cmd_buffer *cmd_buffer,
    const struct anv_subpass *subpass = cmd_buffer->state.subpass;
    const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
    const uint32_t pass_att = subpass->depth_stencil_attachment;
-   const struct anv_image_view *iview = fb->attachments[pass_att];
+   const struct anv_image_view *iview = fb->attachments[pass_att].view;
    const uint32_t samples = iview->image->samples;
    const uint32_t samples_log2 = ffs(samples) - 1;
    VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil;
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index a09403c..4046c6c 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -1730,9 +1730,6 @@ struct anv_image_view {
    VkFormat vk_format;
    VkExtent3D extent; /**< Extent of VkImageViewCreateInfo::baseMipLevel. */
 
-   /** RENDER_SURFACE_STATE when using image as a color render target. */
-   struct anv_state color_rt_surface_state;
-
    /** RENDER_SURFACE_STATE when using image as a sampler surface. */
    struct anv_state sampler_surface_state;
 
@@ -1836,13 +1833,20 @@ struct anv_sampler {
    uint32_t state[4];
 };
 
+struct anv_framebuffer_attachment {
+   struct anv_image_view *                      view;
+   int16_t                                      rt_state_offset;
+};
+
 struct anv_framebuffer {
    uint32_t                                     width;
    uint32_t                                     height;
    uint32_t                                     layers;
 
+   struct anv_state                             surface_states;
+
    uint32_t                                     attachment_count;
-   struct anv_image_view *                      attachments[0];
+   struct anv_framebuffer_attachment            attachments[0];
 };
 
 struct anv_subpass {
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list