anv: Add a new anv_surface_state struct
authorJason Ekstrand <jason.ekstrand@intel.com>
Tue, 11 Jul 2017 18:06:49 +0000 (11:06 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Thu, 21 Sep 2017 00:21:06 +0000 (17:21 -0700)
This struct represents a full surface state including the addresses of
the referenced main and auxiliary surfaces (if any).  This makes
relocation setup substantially simpler and allows us to move 100% of the
surface state setup logic into anv_image where it belongs.  Before, we
were manually fishing data out of surface states when emitting
relocations so we knew how to offset aux address.  It's best to keep all
of the surface state emit logic together.  This also gets us closer, at
least cosmetically, to a world of no relocations where addresses are
placed in surface states up-front.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
src/intel/vulkan/anv_blorp.c
src/intel/vulkan/anv_image.c
src/intel/vulkan/anv_private.h
src/intel/vulkan/genX_cmd_buffer.c

index 915643ffa3ce2f595443d9ff5ea99d56cc9d9c03..7f51bedb76f09c7d12d0825a7f4f0ea928200b08 100644 (file)
@@ -915,7 +915,7 @@ clear_color_attachment(struct anv_cmd_buffer *cmd_buffer,
 
    uint32_t binding_table;
    VkResult result =
-      binding_table_for_surface_state(cmd_buffer, att_state->color_rt_state,
+      binding_table_for_surface_state(cmd_buffer, att_state->color.state,
                                       &binding_table);
    if (result != VK_SUCCESS)
       return;
index f8cb243ad69cda4983576996f3d95109ef72b6f6..b69f76cac3642d8373fb6855c0cdeaa95968b39c 100644 (file)
@@ -721,7 +721,7 @@ anv_image_fill_surface_state(struct anv_device *device,
                              enum isl_aux_usage aux_usage,
                              const union isl_color_value *clear_color,
                              enum anv_image_view_state_flags flags,
-                             struct anv_state *state,
+                             struct anv_surface_state *state_inout,
                              struct brw_image_param *image_param_out)
 {
    const struct anv_surface *surface =
@@ -742,6 +742,10 @@ anv_image_fill_surface_state(struct anv_device *device,
    if (!clear_color)
       clear_color = &default_clear_color;
 
+   const uint64_t address = image->offset + surface->offset;
+   const uint64_t aux_address = (aux_usage == ISL_AUX_USAGE_NONE) ? 0 :
+                                image->offset + image->aux_surface.offset;
+
    if (view_usage == ISL_SURF_USAGE_STORAGE_BIT &&
        !(flags & ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY) &&
        !isl_has_matching_typed_storage_image_format(&device->info,
@@ -751,11 +755,14 @@ anv_image_fill_surface_state(struct anv_device *device,
        * the shader.
        */
       assert(aux_usage == ISL_AUX_USAGE_NONE);
-      isl_buffer_fill_state(&device->isl_dev, state->map,
+      isl_buffer_fill_state(&device->isl_dev, state_inout->state.map,
+                            .address = address,
                             .size = surface->isl.size,
                             .format = ISL_FORMAT_RAW,
                             .stride = 1,
                             .mocs = device->default_mocs);
+      state_inout->address = address,
+      state_inout->aux_address = 0;
    } else {
       if (view_usage == ISL_SURF_USAGE_STORAGE_BIT &&
           !(flags & ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY)) {
@@ -768,16 +775,32 @@ anv_image_fill_surface_state(struct anv_device *device,
                                                       view.format);
       }
 
-      isl_surf_fill_state(&device->isl_dev, state->map,
+      isl_surf_fill_state(&device->isl_dev, state_inout->state.map,
                           .surf = &surface->isl,
                           .view = &view,
+                          .address = address,
                           .clear_color = *clear_color,
                           .aux_surf = &image->aux_surface.isl,
                           .aux_usage = aux_usage,
+                          .aux_address = aux_address,
                           .mocs = device->default_mocs);
+      state_inout->address = address;
+      if (device->info.gen >= 8) {
+         state_inout->aux_address = aux_address;
+      } else {
+         /* 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.
+          */
+         uint32_t *aux_addr_dw = state_inout->state.map +
+                                 device->isl_dev.ss.aux_addr_offset;
+         assert((aux_address & 0xfff) == 0);
+         assert(aux_address == (*aux_addr_dw & 0xfffff000));
+         state_inout->aux_address = *aux_addr_dw;
+      }
    }
 
-   anv_state_flush(device, *state);
+   anv_state_flush(device, state_inout->state);
 
    if (image_param_out) {
       assert(view_usage == ISL_SURF_USAGE_STORAGE_BIT);
@@ -830,12 +853,7 @@ anv_CreateImageView(VkDevice _device,
       break;
    }
 
-   const struct anv_surface *surface =
-      anv_image_get_surface_for_aspect_mask(image, range->aspectMask);
-
    iview->image = image;
-   iview->bo = image->bo;
-   iview->offset = image->offset + surface->offset;
 
    iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask;
    iview->vk_format = pCreateInfo->format;
@@ -888,26 +906,26 @@ anv_CreateImageView(VkDevice _device,
    if (view_usage & VK_IMAGE_USAGE_SAMPLED_BIT ||
        (view_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT &&
         !(iview->aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT))) {
-      iview->optimal_sampler_surface_state = alloc_surface_state(device);
-      iview->general_sampler_surface_state = alloc_surface_state(device);
+      iview->optimal_sampler_surface_state.state = alloc_surface_state(device);
+      iview->general_sampler_surface_state.state = alloc_surface_state(device);
 
-      iview->general_sampler_aux_usage =
+      enum isl_aux_usage general_aux_usage =
          anv_layout_to_aux_usage(&device->info, image, iview->aspect_mask,
                                  VK_IMAGE_LAYOUT_GENERAL);
-      iview->optimal_sampler_aux_usage =
+      enum isl_aux_usage optimal_aux_usage =
          anv_layout_to_aux_usage(&device->info, image, iview->aspect_mask,
                                  VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
 
       anv_image_fill_surface_state(device, image, iview->aspect_mask,
                                    &iview->isl, ISL_SURF_USAGE_TEXTURE_BIT,
-                                   iview->optimal_sampler_aux_usage, NULL,
+                                   optimal_aux_usage, NULL,
                                    ANV_IMAGE_VIEW_STATE_TEXTURE_OPTIMAL,
                                    &iview->optimal_sampler_surface_state,
                                    NULL);
 
       anv_image_fill_surface_state(device, image, iview->aspect_mask,
                                    &iview->isl, ISL_SURF_USAGE_TEXTURE_BIT,
-                                   iview->general_sampler_aux_usage, NULL,
+                                   general_aux_usage, NULL,
                                    0,
                                    &iview->general_sampler_surface_state,
                                    NULL);
@@ -915,8 +933,8 @@ anv_CreateImageView(VkDevice _device,
 
    /* NOTE: This one needs to go last since it may stomp isl_view.format */
    if (view_usage & VK_IMAGE_USAGE_STORAGE_BIT) {
-      iview->storage_surface_state = alloc_surface_state(device);
-      iview->writeonly_storage_surface_state = alloc_surface_state(device);
+      iview->storage_surface_state.state = alloc_surface_state(device);
+      iview->writeonly_storage_surface_state.state = alloc_surface_state(device);
 
       anv_image_fill_surface_state(device, image, iview->aspect_mask,
                                    &iview->isl, ISL_SURF_USAGE_STORAGE_BIT,
@@ -948,24 +966,24 @@ anv_DestroyImageView(VkDevice _device, VkImageView _iview,
    if (!iview)
       return;
 
-   if (iview->optimal_sampler_surface_state.alloc_size > 0) {
+   if (iview->optimal_sampler_surface_state.state.alloc_size > 0) {
       anv_state_pool_free(&device->surface_state_pool,
-                          iview->optimal_sampler_surface_state);
+                          iview->optimal_sampler_surface_state.state);
    }
 
-   if (iview->general_sampler_surface_state.alloc_size > 0) {
+   if (iview->general_sampler_surface_state.state.alloc_size > 0) {
       anv_state_pool_free(&device->surface_state_pool,
-                          iview->general_sampler_surface_state);
+                          iview->general_sampler_surface_state.state);
    }
 
-   if (iview->storage_surface_state.alloc_size > 0) {
+   if (iview->storage_surface_state.state.alloc_size > 0) {
       anv_state_pool_free(&device->surface_state_pool,
-                          iview->storage_surface_state);
+                          iview->storage_surface_state.state);
    }
 
-   if (iview->writeonly_storage_surface_state.alloc_size > 0) {
+   if (iview->writeonly_storage_surface_state.state.alloc_size > 0) {
       anv_state_pool_free(&device->surface_state_pool,
-                          iview->writeonly_storage_surface_state);
+                          iview->writeonly_storage_surface_state.state);
    }
 
    vk_free2(&device->alloc, pAllocator, iview);
index ee7672fc8071462c850231583ea4593b80e94a9f..85843b204b210afc9a1ef5514355b54900843d47 100644 (file)
@@ -1619,6 +1619,23 @@ void anv_dynamic_state_copy(struct anv_dynamic_state *dest,
                             const struct anv_dynamic_state *src,
                             uint32_t copy_mask);
 
+struct anv_surface_state {
+   struct anv_state state;
+   /** Address of the surface referred to by this state
+    *
+    * This address is relative to the start of the BO.
+    */
+   uint64_t address;
+   /* Address of the aux surface, if any
+    *
+    * This field is 0 if and only if no aux surface exists.
+    *
+    * This address is relative to the start of the BO.  On gen7, the bottom 12
+    * bits of this address include extra aux information.
+    */
+   uint64_t aux_address;
+};
+
 /**
  * Attachment state when recording a renderpass instance.
  *
@@ -1627,8 +1644,8 @@ void anv_dynamic_state_copy(struct anv_dynamic_state *dest,
 struct anv_attachment_state {
    enum isl_aux_usage                           aux_usage;
    enum isl_aux_usage                           input_aux_usage;
-   struct anv_state                             color_rt_state;
-   struct anv_state                             input_att_state;
+   struct anv_surface_state                     color;
+   struct anv_surface_state                     input;
 
    VkImageLayout                                current_layout;
    VkImageAspectFlags                           pending_clear_aspects;
@@ -2359,8 +2376,6 @@ anv_get_levelCount(const struct anv_image *image,
 
 struct anv_image_view {
    const struct anv_image *image; /**< VkImageViewCreateInfo::image */
-   struct anv_bo *bo;
-   uint32_t offset; /**< Offset into bo. */
 
    struct isl_view isl;
 
@@ -2372,23 +2387,21 @@ struct anv_image_view {
     * RENDER_SURFACE_STATE when using image as a sampler surface with an image
     * layout of SHADER_READ_ONLY_OPTIMAL or DEPTH_STENCIL_READ_ONLY_OPTIMAL.
     */
-   enum isl_aux_usage optimal_sampler_aux_usage;
-   struct anv_state optimal_sampler_surface_state;
+   struct anv_surface_state optimal_sampler_surface_state;
 
    /**
     * RENDER_SURFACE_STATE when using image as a sampler surface with an image
     * layout of GENERAL.
     */
-   enum isl_aux_usage general_sampler_aux_usage;
-   struct anv_state general_sampler_surface_state;
+   struct anv_surface_state general_sampler_surface_state;
 
    /**
     * RENDER_SURFACE_STATE when using image as a storage image. Separate states
     * for write-only and readable, using the real format for write-only and the
     * lowered format for readable.
     */
-   struct anv_state storage_surface_state;
-   struct anv_state writeonly_storage_surface_state;
+   struct anv_surface_state storage_surface_state;
+   struct anv_surface_state writeonly_storage_surface_state;
 
    struct brw_image_param storage_image_param;
 };
@@ -2406,7 +2419,7 @@ void anv_image_fill_surface_state(struct anv_device *device,
                                   enum isl_aux_usage aux_usage,
                                   const union isl_color_value *clear_color,
                                   enum anv_image_view_state_flags flags,
-                                  struct anv_state *state,
+                                  struct anv_surface_state *state_inout,
                                   struct brw_image_param *image_param_out);
 
 struct anv_image_create_info {
index 188d9e71bca1df61df3a49edcf61b634ef3788bb..7fb607f2189242eb5c021937e70cb5168d9d8bb8 100644 (file)
@@ -179,34 +179,20 @@ add_surface_state_reloc(struct anv_cmd_buffer *cmd_buffer,
 }
 
 static void
-add_image_relocs(struct anv_cmd_buffer * const cmd_buffer,
-                 const struct anv_image * const image,
-                 const VkImageAspectFlags aspect_mask,
-                 const enum isl_aux_usage aux_usage,
-                 const struct anv_state state)
+add_image_relocs(struct anv_cmd_buffer *cmd_buffer,
+                 const struct anv_image *image,
+                 struct anv_surface_state state)
 {
    const struct isl_device *isl_dev = &cmd_buffer->device->isl_dev;
-   const uint32_t surf_offset = image->offset +
-      anv_image_get_surface_for_aspect_mask(image, aspect_mask)->offset;
 
-   add_surface_state_reloc(cmd_buffer, state, image->bo, surf_offset);
-
-   if (aux_usage != ISL_AUX_USAGE_NONE) {
-      uint32_t aux_offset = image->offset + 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;
+   add_surface_state_reloc(cmd_buffer, state.state, image->bo, state.address);
 
+   if (state.aux_address) {
       VkResult result =
          anv_reloc_list_add(&cmd_buffer->surface_relocs,
                             &cmd_buffer->pool->alloc,
-                            state.offset + isl_dev->ss.aux_addr_offset,
-                            image->bo, aux_offset);
+                            state.state.offset + isl_dev->ss.aux_addr_offset,
+                            image->bo, state.aux_address);
       if (result != VK_SUCCESS)
          anv_batch_set_error(&cmd_buffer->batch, result);
    }
@@ -774,8 +760,8 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer,
       /* Create a surface state with the right clear color and perform the
        * resolve.
        */
-      struct anv_state surface_state =
-         anv_cmd_buffer_alloc_surface_state(cmd_buffer);
+      struct anv_surface_state surface_state;
+      surface_state.state = anv_cmd_buffer_alloc_surface_state(cmd_buffer);
       anv_image_fill_surface_state(cmd_buffer->device,
                                    image, VK_IMAGE_ASPECT_COLOR_BIT,
                                    &(struct isl_view) {
@@ -789,14 +775,11 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer,
                                    ISL_SURF_USAGE_RENDER_TARGET_BIT,
                                    aux_usage, NULL, 0,
                                    &surface_state, NULL);
-      add_image_relocs(cmd_buffer, image, VK_IMAGE_ASPECT_COLOR_BIT,
-                       image->aux_usage == ISL_AUX_USAGE_CCS_E ?
-                       ISL_AUX_USAGE_CCS_E : ISL_AUX_USAGE_CCS_D,
-                       surface_state);
-      anv_state_flush(cmd_buffer->device, surface_state);
-      genX(copy_fast_clear_dwords)(cmd_buffer, surface_state, image, level,
-                                   false /* copy to ss */);
-      anv_ccs_resolve(cmd_buffer, surface_state, image, level, layer_count,
+      add_image_relocs(cmd_buffer, image, surface_state);
+      genX(copy_fast_clear_dwords)(cmd_buffer, surface_state.state, image,
+                                   level, false /* copy to ss */);
+      anv_ccs_resolve(cmd_buffer, surface_state.state, image,
+                      level, layer_count,
                       image->aux_usage == ISL_AUX_USAGE_CCS_E ?
                       BLORP_FAST_CLEAR_OP_RESOLVE_PARTIAL :
                       BLORP_FAST_CLEAR_OP_RESOLVE_FULL);
@@ -859,13 +842,13 @@ genX(cmd_buffer_setup_attachments)(struct anv_cmd_buffer *cmd_buffer,
 
    for (uint32_t i = 0; i < pass->attachment_count; ++i) {
       if (vk_format_is_color(pass->attachments[i].format)) {
-         state->attachments[i].color_rt_state = next_state;
+         state->attachments[i].color.state = next_state;
          next_state.offset += ss_stride;
          next_state.map += ss_stride;
       }
 
       if (need_input_attachment_state(&pass->attachments[i])) {
-         state->attachments[i].input_att_state = next_state;
+         state->attachments[i].input.state = next_state;
          next_state.offset += ss_stride;
          next_state.map += ss_stride;
       }
@@ -926,12 +909,11 @@ genX(cmd_buffer_setup_attachments)(struct anv_cmd_buffer *cmd_buffer,
                                          state->attachments[i].aux_usage,
                                          &clear_color,
                                          0,
-                                         &state->attachments[i].color_rt_state,
+                                         &state->attachments[i].color,
                                          NULL);
 
-            add_image_relocs(cmd_buffer, iview->image, iview->aspect_mask,
-                             state->attachments[i].aux_usage,
-                             state->attachments[i].color_rt_state);
+            add_image_relocs(cmd_buffer, iview->image,
+                             state->attachments[i].color);
          } else {
             /* This field will be initialized after the first subpass
              * transition.
@@ -950,12 +932,11 @@ genX(cmd_buffer_setup_attachments)(struct anv_cmd_buffer *cmd_buffer,
                                          state->attachments[i].input_aux_usage,
                                          &clear_color,
                                          0,
-                                         &state->attachments[i].input_att_state,
+                                         &state->attachments[i].input,
                                          NULL);
 
-            add_image_relocs(cmd_buffer, iview->image, iview->aspect_mask,
-                             state->attachments[i].input_aux_usage,
-                             state->attachments[i].input_att_state);
+            add_image_relocs(cmd_buffer, iview->image,
+                             state->attachments[i].input);
          }
       }
    }
@@ -1553,7 +1534,7 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
             if (att == VK_ATTACHMENT_UNUSED) {
                surface_state = cmd_buffer->state.null_surface_state;
             } else {
-               surface_state = cmd_buffer->state.attachments[att].color_rt_state;
+               surface_state = cmd_buffer->state.attachments[att].color.state;
             }
          } else {
             surface_state = cmd_buffer->state.null_surface_state;
@@ -1575,18 +1556,13 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
 
       case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
       case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: {
-         enum isl_aux_usage aux_usage;
-         if (desc->layout == VK_IMAGE_LAYOUT_GENERAL) {
-            surface_state = desc->image_view->general_sampler_surface_state;
-            aux_usage = desc->image_view->general_sampler_aux_usage;
-         } else {
-            surface_state = desc->image_view->optimal_sampler_surface_state;
-            aux_usage = desc->image_view->optimal_sampler_aux_usage;
-         }
+         struct anv_surface_state sstate =
+            (desc->layout == VK_IMAGE_LAYOUT_GENERAL) ?
+            desc->image_view->general_sampler_surface_state :
+            desc->image_view->optimal_sampler_surface_state;
+         surface_state = sstate.state;
          assert(surface_state.alloc_size);
-         add_image_relocs(cmd_buffer, desc->image_view->image,
-                          desc->image_view->aspect_mask,
-                          aux_usage, surface_state);
+         add_image_relocs(cmd_buffer, desc->image_view->image, sstate);
          break;
       }
       case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
@@ -1595,18 +1571,13 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
             /* For depth and stencil input attachments, we treat it like any
              * old texture that a user may have bound.
              */
-            enum isl_aux_usage aux_usage;
-            if (desc->layout == VK_IMAGE_LAYOUT_GENERAL) {
-               surface_state = desc->image_view->general_sampler_surface_state;
-               aux_usage = desc->image_view->general_sampler_aux_usage;
-            } else {
-               surface_state = desc->image_view->optimal_sampler_surface_state;
-               aux_usage = desc->image_view->optimal_sampler_aux_usage;
-            }
+            struct anv_surface_state sstate =
+               (desc->layout == VK_IMAGE_LAYOUT_GENERAL) ?
+               desc->image_view->general_sampler_surface_state :
+               desc->image_view->optimal_sampler_surface_state;
+            surface_state = sstate.state;
             assert(surface_state.alloc_size);
-            add_image_relocs(cmd_buffer, desc->image_view->image,
-                             desc->image_view->aspect_mask,
-                             aux_usage, surface_state);
+            add_image_relocs(cmd_buffer, desc->image_view->image, sstate);
          } else {
             /* For color input attachments, we create the surface state at
              * vkBeginRenderPass time so that we can include aux and clear
@@ -1615,18 +1586,17 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
             assert(binding->input_attachment_index < subpass->input_count);
             const unsigned subpass_att = binding->input_attachment_index;
             const unsigned att = subpass->input_attachments[subpass_att].attachment;
-            surface_state = cmd_buffer->state.attachments[att].input_att_state;
+            surface_state = cmd_buffer->state.attachments[att].input.state;
          }
          break;
 
       case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
-         surface_state = (binding->write_only)
+         struct anv_surface_state sstate = (binding->write_only)
             ? desc->image_view->writeonly_storage_surface_state
             : desc->image_view->storage_surface_state;
+         surface_state = sstate.state;
          assert(surface_state.alloc_size);
-         add_image_relocs(cmd_buffer, desc->image_view->image,
-                          desc->image_view->aspect_mask,
-                          desc->image_view->image->aux_usage, surface_state);
+         add_image_relocs(cmd_buffer, desc->image_view->image, sstate);
 
          struct brw_image_param *image_param =
             &cmd_buffer->state.push_constants[stage]->images[image++];
@@ -2951,7 +2921,7 @@ cmd_buffer_subpass_sync_fast_clear_values(struct anv_cmd_buffer *cmd_buffer)
        */
       if (att_state->pending_clear_aspects && att_state->fast_clear) {
          /* Update the fast clear state entry. */
-         genX(copy_fast_clear_dwords)(cmd_buffer, att_state->color_rt_state,
+         genX(copy_fast_clear_dwords)(cmd_buffer, att_state->color.state,
                                       iview->image, iview->isl.base_level,
                                       true /* copy from ss */);
 
@@ -2975,13 +2945,13 @@ cmd_buffer_subpass_sync_fast_clear_values(struct anv_cmd_buffer *cmd_buffer)
           *
           * TODO: Do this only once per render pass instead of every subpass.
           */
-         genX(copy_fast_clear_dwords)(cmd_buffer, att_state->color_rt_state,
+         genX(copy_fast_clear_dwords)(cmd_buffer, att_state->color.state,
                                       iview->image, iview->isl.base_level,
                                       false /* copy to ss */);
 
          if (need_input_attachment_state(rp_att) &&
              att_state->input_aux_usage != ISL_AUX_USAGE_NONE) {
-            genX(copy_fast_clear_dwords)(cmd_buffer, att_state->input_att_state,
+            genX(copy_fast_clear_dwords)(cmd_buffer, att_state->input.state,
                                          iview->image, iview->isl.base_level,
                                          false /* copy to ss */);
          }