anv: Add anv_cmd_state::attachments
authorChad Versace <chad.versace@intel.com>
Wed, 13 Jan 2016 19:28:35 +0000 (11:28 -0800)
committerChad Versace <chad.versace@intel.com>
Fri, 15 Jan 2016 06:53:05 +0000 (22:53 -0800)
This array contains attachment state when recording a renderpass instance.
It's populated on each call to anv_cmd_buffer_set_pass.

The data is currently set but unused. We'll use it later to defer each
attachment clear to the subpass that first uses the attachment.

src/vulkan/anv_cmd_buffer.c
src/vulkan/anv_private.h
src/vulkan/gen7_cmd_buffer.c
src/vulkan/gen8_cmd_buffer.c

index 689bc53c93a811903be867a93b52d9f40b12b039..065c2f6492271546b8ec5f459b1922c13835c2a4 100644 (file)
@@ -111,8 +111,10 @@ anv_dynamic_state_copy(struct anv_dynamic_state *dest,
 }
 
 static void
-anv_cmd_state_reset(struct anv_cmd_state *state)
+anv_cmd_state_reset(struct anv_cmd_buffer *cmd_buffer)
 {
+   struct anv_cmd_state *state = &cmd_buffer->state;
+
    memset(&state->descriptors, 0, sizeof(state->descriptors));
    memset(&state->push_constants, 0, sizeof(state->push_constants));
 
@@ -125,9 +127,69 @@ anv_cmd_state_reset(struct anv_cmd_state *state)
    state->dynamic = default_dynamic_state;
    state->need_query_wa = true;
 
+   if (state->attachments != NULL) {
+      anv_free(&cmd_buffer->pool->alloc, state->attachments);
+      state->attachments = NULL;
+   }
+
    state->gen7.index_buffer = NULL;
 }
 
+/**
+ * Setup anv_cmd_state::attachments for vkCmdBeginRenderPass.
+ */
+void
+anv_cmd_state_setup_attachments(struct anv_cmd_buffer *cmd_buffer,
+                                const VkRenderPassBeginInfo *info)
+{
+   struct anv_cmd_state *state = &cmd_buffer->state;
+   ANV_FROM_HANDLE(anv_render_pass, pass, info->renderPass);
+
+   anv_free(&cmd_buffer->pool->alloc, state->attachments);
+
+   if (pass->attachment_count == 0) {
+      state->attachments = NULL;
+      return;
+   }
+
+   state->attachments = anv_alloc(&cmd_buffer->pool->alloc,
+                                  pass->attachment_count *
+                                       sizeof(state->attachments[0]),
+                                  8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+   if (state->attachments == NULL) {
+      /* FIXME: Propagate VK_ERROR_OUT_OF_HOST_MEMORY to vkEndCommandBuffer */
+      abort();
+   }
+
+   for (uint32_t i = 0; i < pass->attachment_count; ++i) {
+      struct anv_render_pass_attachment *att = &pass->attachments[i];
+      VkImageAspectFlags clear_aspects = 0;
+
+      if (anv_format_is_color(att->format)) {
+         /* color attachment */
+         if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
+            clear_aspects |= VK_IMAGE_ASPECT_COLOR_BIT;
+         }
+      } else {
+         /* depthstencil attachment */
+         if (att->format->depth_format &&
+             att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
+            clear_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
+         }
+         if (att->format->has_stencil &&
+             att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
+            clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
+         }
+      }
+
+      state->attachments[i].pending_clear_aspects = clear_aspects;
+      if (clear_aspects) {
+         assert(info->clearValueCount > i);
+         state->attachments[i].clear_value = info->pClearValues[i];
+      }
+   }
+}
+
 static VkResult
 anv_cmd_buffer_ensure_push_constants_size(struct anv_cmd_buffer *cmd_buffer,
                                           gl_shader_stage stage, uint32_t size)
@@ -173,6 +235,7 @@ static VkResult anv_create_cmd_buffer(
    cmd_buffer->device = device;
    cmd_buffer->pool = pool;
    cmd_buffer->level = level;
+   cmd_buffer->state.attachments = NULL;
 
    result = anv_cmd_buffer_init_batch_bo_chain(cmd_buffer);
    if (result != VK_SUCCESS)
@@ -237,6 +300,7 @@ anv_cmd_buffer_destroy(struct anv_cmd_buffer *cmd_buffer)
    anv_state_stream_finish(&cmd_buffer->surface_state_stream);
    anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
 
+   anv_free(&cmd_buffer->pool->alloc, cmd_buffer->state.attachments);
    anv_free(&cmd_buffer->pool->alloc, cmd_buffer);
 }
 
@@ -262,7 +326,7 @@ VkResult anv_ResetCommandBuffer(
    cmd_buffer->usage_flags = 0;
    cmd_buffer->state.current_pipeline = UINT32_MAX;
    anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer);
-   anv_cmd_state_reset(&cmd_buffer->state);
+   anv_cmd_state_reset(cmd_buffer);
 
    return VK_SUCCESS;
 }
index 1065f8a73597f7fb61ee1e701860bc7e06289340..f3232c690292a46e45b9317330acf285c8bff604 100644 (file)
@@ -1059,6 +1059,16 @@ void anv_dynamic_state_copy(struct anv_dynamic_state *dest,
                             const struct anv_dynamic_state *src,
                             uint32_t copy_mask);
 
+/**
+ * Attachment state when recording a renderpass instance.
+ *
+ * The clear value is valid only if there exists a pending clear.
+ */
+struct anv_attachment_state {
+   VkImageAspectFlags                           pending_clear_aspects;
+   VkClearValue                                 clear_value;
+};
+
 /** State required while building cmd buffer */
 struct anv_cmd_state {
    /* PIPELINE_SELECT.PipelineSelection */
@@ -1085,6 +1095,12 @@ struct anv_cmd_state {
    struct anv_dynamic_state                     dynamic;
    bool                                         need_query_wa;
 
+   /**
+    * Array length is anv_cmd_state::pass::attachment_count. Array content is
+    * valid only when recording a render pass instance.
+    */
+   struct anv_attachment_state *                attachments;
+
    struct {
       struct anv_buffer *                       index_buffer;
       uint32_t                                  index_type; /**< 3DSTATE_INDEX_BUFFER.IndexFormat */
@@ -1214,6 +1230,8 @@ void gen9_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer);
 
 void anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer);
 
+void anv_cmd_state_setup_attachments(struct anv_cmd_buffer *cmd_buffer,
+                                     const VkRenderPassBeginInfo *info);
 void gen7_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
                                    struct anv_subpass *subpass);
 
index e6501124139dbe6ae39c358de056e1f3bf82d6b0..7309b1688f5558df34b6e7c4f6c8a91ff5266ef8 100644 (file)
@@ -816,6 +816,7 @@ void genX(CmdBeginRenderPass)(
 
    cmd_buffer->state.framebuffer = framebuffer;
    cmd_buffer->state.pass = pass;
+   anv_cmd_state_setup_attachments(cmd_buffer, pRenderPassBegin);
 
    const VkRect2D *render_area = &pRenderPassBegin->renderArea;
 
index 65b4514d35e5081831f60710092b133c0e7a38f1..0e2b3047bcd233c47f035b3143fe89be3ceaa52e 100644 (file)
@@ -813,6 +813,7 @@ void genX(CmdBeginRenderPass)(
 
    cmd_buffer->state.framebuffer = framebuffer;
    cmd_buffer->state.pass = pass;
+   anv_cmd_state_setup_attachments(cmd_buffer, pRenderPassBegin);
 
    flush_pipeline_select_3d(cmd_buffer);