anv: Set up binding tables and surface states for input attachments
authorJason Ekstrand <jason.ekstrand@intel.com>
Tue, 15 Nov 2016 23:25:55 +0000 (15:25 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Tue, 22 Nov 2016 21:44:55 +0000 (13:44 -0800)
This commit adds the last remaining bits to support input attachments in
the Intel Vulkan driver.  For color and depth attachments, we allocate an
input attachment surface state during vkCmdBeginRenderPass like we do for
the render target surface states.  This is so that we can incorporate the
clear color and aux information as used in rendering.  For stencil, we just
treat it like a regular texture because we don't there is no aux.  Also,
only having to worry about at most one input attachment surface for each
attachment makes some of the vkCmdBeginRenderPass code simpler.

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
src/intel/vulkan/anv_descriptor_set.c
src/intel/vulkan/anv_image.c
src/intel/vulkan/anv_private.h
src/intel/vulkan/genX_cmd_buffer.c
src/intel/vulkan/vk_format_info.h

index 578bf7bee6a416aa05e50f70269708c626c8323c..2926e7a259141667fddf923cdefddc902603240b 100644 (file)
@@ -617,6 +617,7 @@ void anv_UpdateDescriptorSets(
 
       case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
       case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+      case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
          for (uint32_t j = 0; j < write->descriptorCount; j++) {
             ANV_FROM_HANDLE(anv_image_view, iview,
                             write->pImageInfo[j].imageView);
@@ -641,10 +642,6 @@ void anv_UpdateDescriptorSets(
          }
          break;
 
-      case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
-         anv_finishme("input attachments not implemented");
-         break;
-
       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
index ed221a7730e00293c17dcd39d3b410323535eb45..6f19c84df9962ee184007ff0f4e165fad452bb33 100644 (file)
@@ -521,7 +521,14 @@ anv_CreateImageView(VkDevice _device,
       iview->isl.usage = 0;
    }
 
-   if (image->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
+   /* Input attachment surfaces for color or depth are allocated and filled
+    * out at BeginRenderPass time because they need compression information.
+    * Stencil image do not support compression so we just use the texture
+    * surface from the image view.
+    */
+   if (image->usage & VK_IMAGE_USAGE_SAMPLED_BIT ||
+       (image->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT &&
+        (iview->aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT))) {
       iview->sampler_surface_state = alloc_surface_state(device);
 
       struct isl_view view = iview->isl;
index 4fa4f32bcbeb9c21000c7588ae21e4eec88c5518..7b521b1268dab27fae9c906f57d2b238bd61086d 100644 (file)
@@ -1088,6 +1088,7 @@ void anv_dynamic_state_copy(struct anv_dynamic_state *dest,
 struct anv_attachment_state {
    enum isl_aux_usage                           aux_usage;
    struct anv_state                             color_rt_state;
+   struct anv_state                             input_att_state;
 
    VkImageAspectFlags                           pending_clear_aspects;
    VkClearValue                                 clear_value;
index 5e4979fbb6d8b28bf893a4ea99ed27ccce566d70..418384221709e5eff21326909c4cbafc3c22667c 100644 (file)
@@ -210,6 +210,19 @@ fb_attachment_get_aux_usage(struct anv_device *device,
    return ISL_AUX_USAGE_NONE;
 }
 
+static bool
+need_input_attachment_state(const struct anv_render_pass_attachment *att)
+{
+   if (!(att->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))
+      return false;
+
+   /* We only allocate input attachment states for color and depth surfaces.
+    * Stencil doesn't allow compression so we can just use the texture surface
+    * state from the view
+    */
+   return vk_format_is_color(att->format) || vk_format_has_depth(att->format);
+}
+
 /**
  * Setup anv_cmd_state::attachments for vkCmdBeginRenderPass.
  */
@@ -250,6 +263,9 @@ genX(cmd_buffer_setup_attachments)(struct anv_cmd_buffer *cmd_buffer,
           */
          need_null_state = true;
       }
+
+      if (need_input_attachment_state(&pass->attachments[i]))
+         num_states++;
    }
    num_states += need_null_state;
 
@@ -273,6 +289,12 @@ genX(cmd_buffer_setup_attachments)(struct anv_cmd_buffer *cmd_buffer,
          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;
+         next_state.offset += ss_stride;
+         next_state.map += ss_stride;
+      }
    }
    assert(next_state.offset == state->render_pass_states.offset +
                                state->render_pass_states.alloc_size);
@@ -348,6 +370,29 @@ genX(cmd_buffer_setup_attachments)(struct anv_cmd_buffer *cmd_buffer,
          } else {
             state->attachments[i].aux_usage = ISL_AUX_USAGE_NONE;
          }
+
+         if (need_input_attachment_state(&pass->attachments[i])) {
+            const struct isl_surf *surf;
+            if (att_aspects == VK_IMAGE_ASPECT_COLOR_BIT) {
+               surf = &iview->image->color_surface.isl;
+            } else {
+               surf = &iview->image->depth_surface.isl;
+            }
+
+            struct isl_view view = iview->isl;
+            view.usage |= ISL_SURF_USAGE_TEXTURE_BIT;
+            isl_surf_fill_state(isl_dev,
+                                state->attachments[i].input_att_state.map,
+                                .surf = surf,
+                                .view = &view,
+                                .aux_surf = &iview->image->aux_surface.isl,
+                                .aux_usage = state->attachments[i].aux_usage,
+                                .mocs = cmd_buffer->device->default_mocs);
+
+            add_image_view_relocs(cmd_buffer, iview,
+                                  state->attachments[i].aux_usage,
+                                  state->attachments[i].input_att_state);
+         }
       }
 
       if (!cmd_buffer->device->info.has_llc)
@@ -942,7 +987,6 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
 
       case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
       case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
-      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,
@@ -950,6 +994,29 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
                                surface_state);
          break;
 
+      case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
+         assert(stage == MESA_SHADER_FRAGMENT);
+         if (desc->image_view->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) {
+            /* For stencil input attachments, we treat it like any old texture
+             * that a user may have bound.
+             */
+            surface_state = desc->image_view->sampler_surface_state;
+            assert(surface_state.alloc_size);
+            add_image_view_relocs(cmd_buffer, desc->image_view,
+                                  desc->image_view->image->aux_usage,
+                                  surface_state);
+         } else {
+            /* For depth and color input attachments, we create the surface
+             * state at vkBeginRenderPass time so that we can include aux
+             * and clear color information.
+             */
+            assert(binding->input_attachment_index < subpass->input_count);
+            const unsigned subpass_att = binding->input_attachment_index;
+            const unsigned att = subpass->input_attachments[subpass_att];
+            surface_state = cmd_buffer->state.attachments[att].input_att_state;
+         }
+         break;
+
       case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
          surface_state = desc->image_view->storage_surface_state;
          assert(surface_state.alloc_size);
index 5c5a1f3cc16879e516da5c51fae8aaee49cfacee..a680a6f24b319d4248c8589cfc62a6990d30cbd2 100644 (file)
@@ -65,4 +65,11 @@ vk_format_is_depth_or_stencil(VkFormat format)
    return aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
 }
 
+static inline bool
+vk_format_has_depth(VkFormat format)
+{
+   const VkImageAspectFlags aspects = vk_format_aspects(format);
+   return aspects & VK_IMAGE_ASPECT_DEPTH_BIT;
+}
+
 #endif /* VK_FORMAT_INFO_H */