From a4b045ca44fb8210537e5a2b7c772f836be20e97 Mon Sep 17 00:00:00 2001 From: Chad Versace Date: Wed, 13 Jan 2016 11:28:35 -0800 Subject: [PATCH] anv: Add anv_cmd_state::attachments 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 | 68 ++++++++++++++++++++++++++++++++++++++++++-- src/vulkan/anv_private.h | 18 ++++++++++++ src/vulkan/gen7_cmd_buffer.c | 1 + src/vulkan/gen8_cmd_buffer.c | 1 + 4 files changed, 86 insertions(+), 2 deletions(-) diff --git a/src/vulkan/anv_cmd_buffer.c b/src/vulkan/anv_cmd_buffer.c index 689bc53..065c2f6 100644 --- a/src/vulkan/anv_cmd_buffer.c +++ b/src/vulkan/anv_cmd_buffer.c @@ -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; } diff --git a/src/vulkan/anv_private.h b/src/vulkan/anv_private.h index 1065f8a..f3232c6 100644 --- a/src/vulkan/anv_private.h +++ b/src/vulkan/anv_private.h @@ -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); diff --git a/src/vulkan/gen7_cmd_buffer.c b/src/vulkan/gen7_cmd_buffer.c index e650112..7309b16 100644 --- a/src/vulkan/gen7_cmd_buffer.c +++ b/src/vulkan/gen7_cmd_buffer.c @@ -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; diff --git a/src/vulkan/gen8_cmd_buffer.c b/src/vulkan/gen8_cmd_buffer.c index 65b4514..0e2b304 100644 --- a/src/vulkan/gen8_cmd_buffer.c +++ b/src/vulkan/gen8_cmd_buffer.c @@ -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); -- 2.7.4