[Mesa-dev] [PATCH 18/22] anv: Use blorp for subpass clears
Pohjolainen, Topi
topi.pohjolainen at gmail.com
Wed Oct 12 09:40:49 UTC 2016
On Fri, Oct 07, 2016 at 09:41:16PM -0700, Jason Ekstrand wrote:
> Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
> ---
> src/intel/vulkan/anv_blorp.c | 81 +++++++++++
> src/intel/vulkan/anv_meta_clear.c | 298 --------------------------------------
> 2 files changed, 81 insertions(+), 298 deletions(-)
>
> diff --git a/src/intel/vulkan/anv_blorp.c b/src/intel/vulkan/anv_blorp.c
> index 4279f62..968c887 100644
> --- a/src/intel/vulkan/anv_blorp.c
> +++ b/src/intel/vulkan/anv_blorp.c
> @@ -982,6 +982,87 @@ void anv_CmdClearAttachments(
> blorp_batch_finish(&batch);
> }
>
> +static bool
> +subpass_needs_clear(const struct anv_cmd_buffer *cmd_buffer)
> +{
> + const struct anv_cmd_state *cmd_state = &cmd_buffer->state;
> + uint32_t ds = cmd_state->subpass->depth_stencil_attachment;
> +
> + for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
> + uint32_t a = cmd_state->subpass->color_attachments[i];
> + if (cmd_state->attachments[a].pending_clear_aspects) {
> + return true;
> + }
> + }
> +
> + if (ds != VK_ATTACHMENT_UNUSED &&
> + cmd_state->attachments[ds].pending_clear_aspects) {
> + return true;
> + }
> +
> + return false;
> +}
> +
> +void
> +anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer)
> +{
> + const struct anv_cmd_state *cmd_state = &cmd_buffer->state;
> +
> + if (!subpass_needs_clear(cmd_buffer))
> + return;
> +
> + /* Because this gets called within a render pass, we tell blorp not to
> + * trash our depth and stencil buffers.
> + */
> + struct blorp_batch batch;
> + blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer,
> + BLORP_BATCH_NO_EMIT_DEPTH_STENCIL);
> +
> + VkClearRect clear_rect = {
Could be const.
> + .rect = cmd_buffer->state.render_area,
> + .baseArrayLayer = 0,
> + .layerCount = cmd_buffer->state.framebuffer->layers,
> + };
> +
> + for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
> + uint32_t a = cmd_state->subpass->color_attachments[i];
As well.
> +
> + if (!cmd_state->attachments[a].pending_clear_aspects)
> + continue;
> +
> + assert(cmd_state->attachments[a].pending_clear_aspects ==
> + VK_IMAGE_ASPECT_COLOR_BIT);
> +
> + VkClearAttachment clear_att = {
And this.
> + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
> + .colorAttachment = i, /* Use attachment index relative to subpass */
> + .clearValue = cmd_state->attachments[a].clear_value,
> + };
> +
> + clear_color_attachment(cmd_buffer, &batch, &clear_att, 1, &clear_rect);
> +
> + cmd_state->attachments[a].pending_clear_aspects = 0;
> + }
> +
> + uint32_t ds = cmd_state->subpass->depth_stencil_attachment;
And this.
> +
> + if (ds != VK_ATTACHMENT_UNUSED &&
> + cmd_state->attachments[ds].pending_clear_aspects) {
> +
> + VkClearAttachment clear_att = {
And this.
All in all looks quite a bit simpler:
Reviewed-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
> + .aspectMask = cmd_state->attachments[ds].pending_clear_aspects,
> + .clearValue = cmd_state->attachments[ds].clear_value,
> + };
> +
> + clear_depth_stencil_attachment(cmd_buffer, &batch,
> + &clear_att, 1, &clear_rect);
> +
> + cmd_state->attachments[ds].pending_clear_aspects = 0;
> + }
> +
> + blorp_batch_finish(&batch);
> +}
> +
> static void
> resolve_image(struct blorp_batch *batch,
> const struct anv_image *src_image,
> diff --git a/src/intel/vulkan/anv_meta_clear.c b/src/intel/vulkan/anv_meta_clear.c
> index 6802229..2bc718b 100644
> --- a/src/intel/vulkan/anv_meta_clear.c
> +++ b/src/intel/vulkan/anv_meta_clear.c
> @@ -41,26 +41,6 @@ struct depthstencil_clear_vattrs {
> };
>
> static void
> -meta_clear_begin(struct anv_meta_saved_state *saved_state,
> - struct anv_cmd_buffer *cmd_buffer)
> -{
> - anv_meta_save(saved_state, cmd_buffer,
> - (1 << VK_DYNAMIC_STATE_VIEWPORT) |
> - (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE) |
> - (1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK));
> -
> - /* Avoid uploading more viewport states than necessary */
> - cmd_buffer->state.dynamic.viewport.count = 0;
> -}
> -
> -static void
> -meta_clear_end(struct anv_meta_saved_state *saved_state,
> - struct anv_cmd_buffer *cmd_buffer)
> -{
> - anv_meta_restore(saved_state, cmd_buffer);
> -}
> -
> -static void
> build_color_shaders(struct nir_shader **out_vs,
> struct nir_shader **out_fs,
> uint32_t frag_output)
> @@ -337,80 +317,6 @@ anv_device_finish_meta_clear_state(struct anv_device *device)
> }
>
> static void
> -emit_color_clear(struct anv_cmd_buffer *cmd_buffer,
> - const VkClearAttachment *clear_att,
> - const VkClearRect *clear_rect)
> -{
> - struct anv_device *device = cmd_buffer->device;
> - const struct anv_subpass *subpass = cmd_buffer->state.subpass;
> - 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 uint32_t samples = iview->image->samples;
> - const uint32_t samples_log2 = ffs(samples) - 1;
> - struct anv_pipeline *pipeline =
> - device->meta_state.clear[samples_log2].color_pipelines[subpass_att];
> - VkClearColorValue clear_value = clear_att->clearValue.color;
> -
> - VkCommandBuffer cmd_buffer_h = anv_cmd_buffer_to_handle(cmd_buffer);
> - VkPipeline pipeline_h = anv_pipeline_to_handle(pipeline);
> -
> - assert(samples_log2 < ARRAY_SIZE(device->meta_state.clear));
> - assert(clear_att->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
> - assert(clear_att->colorAttachment < subpass->color_count);
> -
> - const struct color_clear_vattrs vertex_data[3] = {
> - {
> - .vue_header = { 0 },
> - .position = {
> - clear_rect->rect.offset.x,
> - clear_rect->rect.offset.y,
> - },
> - .color = clear_value,
> - },
> - {
> - .vue_header = { 0 },
> - .position = {
> - clear_rect->rect.offset.x + clear_rect->rect.extent.width,
> - clear_rect->rect.offset.y,
> - },
> - .color = clear_value,
> - },
> - {
> - .vue_header = { 0 },
> - .position = {
> - clear_rect->rect.offset.x + clear_rect->rect.extent.width,
> - clear_rect->rect.offset.y + clear_rect->rect.extent.height,
> - },
> - .color = clear_value,
> - },
> - };
> -
> - struct anv_state state =
> - anv_cmd_buffer_emit_dynamic(cmd_buffer, vertex_data, sizeof(vertex_data), 16);
> -
> - struct anv_buffer vertex_buffer = {
> - .device = device,
> - .size = sizeof(vertex_data),
> - .bo = &device->dynamic_state_block_pool.bo,
> - .offset = state.offset,
> - };
> -
> - ANV_CALL(CmdBindVertexBuffers)(cmd_buffer_h, 0, 1,
> - (VkBuffer[]) { anv_buffer_to_handle(&vertex_buffer) },
> - (VkDeviceSize[]) { 0 });
> -
> - if (cmd_buffer->state.pipeline != pipeline) {
> - ANV_CALL(CmdBindPipeline)(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
> - pipeline_h);
> - }
> -
> - ANV_CALL(CmdDraw)(cmd_buffer_h, 3, 1, 0, 0);
> -}
> -
> -
> -static void
> build_depthstencil_shader(struct nir_shader **out_vs)
> {
> nir_builder vs_b;
> @@ -503,111 +409,6 @@ create_depthstencil_pipeline(struct anv_device *device,
> /*use_repclear*/ true, pipeline);
> }
>
> -static void
> -emit_depthstencil_clear(struct anv_cmd_buffer *cmd_buffer,
> - const VkClearAttachment *clear_att,
> - const VkClearRect *clear_rect)
> -{
> - struct anv_device *device = cmd_buffer->device;
> - struct anv_meta_state *meta_state = &device->meta_state;
> - 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 uint32_t samples = iview->image->samples;
> - const uint32_t samples_log2 = ffs(samples) - 1;
> - VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil;
> - VkImageAspectFlags aspects = clear_att->aspectMask;
> -
> - VkCommandBuffer cmd_buffer_h = anv_cmd_buffer_to_handle(cmd_buffer);
> -
> - assert(samples_log2 < ARRAY_SIZE(meta_state->clear));
> - assert(aspects == VK_IMAGE_ASPECT_DEPTH_BIT ||
> - aspects == VK_IMAGE_ASPECT_STENCIL_BIT ||
> - aspects == (VK_IMAGE_ASPECT_DEPTH_BIT |
> - VK_IMAGE_ASPECT_STENCIL_BIT));
> - assert(pass_att != VK_ATTACHMENT_UNUSED);
> -
> - const struct depthstencil_clear_vattrs vertex_data[3] = {
> - {
> - .vue_header = { 0 },
> - .position = {
> - clear_rect->rect.offset.x,
> - clear_rect->rect.offset.y,
> - },
> - },
> - {
> - .vue_header = { 0 },
> - .position = {
> - clear_rect->rect.offset.x + clear_rect->rect.extent.width,
> - clear_rect->rect.offset.y,
> - },
> - },
> - {
> - .vue_header = { 0 },
> - .position = {
> - clear_rect->rect.offset.x + clear_rect->rect.extent.width,
> - clear_rect->rect.offset.y + clear_rect->rect.extent.height,
> - },
> - },
> - };
> -
> - struct anv_state state =
> - anv_cmd_buffer_emit_dynamic(cmd_buffer, vertex_data, sizeof(vertex_data), 16);
> -
> - struct anv_buffer vertex_buffer = {
> - .device = device,
> - .size = sizeof(vertex_data),
> - .bo = &device->dynamic_state_block_pool.bo,
> - .offset = state.offset,
> - };
> -
> - ANV_CALL(CmdSetViewport)(cmd_buffer_h, 0, 1,
> - (VkViewport[]) {
> - {
> - .x = 0,
> - .y = 0,
> - .width = fb->width,
> - .height = fb->height,
> -
> - /* Ignored when clearing only stencil. */
> - .minDepth = clear_value.depth,
> - .maxDepth = clear_value.depth,
> - },
> - });
> -
> - if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
> - ANV_CALL(CmdSetStencilReference)(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT,
> - clear_value.stencil);
> - }
> -
> - ANV_CALL(CmdBindVertexBuffers)(cmd_buffer_h, 0, 1,
> - (VkBuffer[]) { anv_buffer_to_handle(&vertex_buffer) },
> - (VkDeviceSize[]) { 0 });
> -
> - struct anv_pipeline *pipeline;
> - switch (aspects) {
> - case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
> - pipeline = meta_state->clear[samples_log2].depthstencil_pipeline;
> - break;
> - case VK_IMAGE_ASPECT_DEPTH_BIT:
> - pipeline = meta_state->clear[samples_log2].depth_only_pipeline;
> - break;
> - case VK_IMAGE_ASPECT_STENCIL_BIT:
> - pipeline = meta_state->clear[samples_log2].stencil_only_pipeline;
> - break;
> - default:
> - unreachable("expected depth or stencil aspect");
> - }
> -
> - if (cmd_buffer->state.pipeline != pipeline) {
> - ANV_CALL(CmdBindPipeline)(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
> - anv_pipeline_to_handle(pipeline));
> - }
> -
> - ANV_CALL(CmdDraw)(cmd_buffer_h, 3, 1, 0, 0);
> -}
> -
> VkResult
> anv_device_init_meta_clear_state(struct anv_device *device)
> {
> @@ -652,102 +453,3 @@ fail:
> anv_device_finish_meta_clear_state(device);
> return res;
> }
> -
> -/**
> - * The parameters mean that same as those in vkCmdClearAttachments.
> - */
> -static void
> -emit_clear(struct anv_cmd_buffer *cmd_buffer,
> - const VkClearAttachment *clear_att,
> - const VkClearRect *clear_rect)
> -{
> - if (clear_att->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
> - emit_color_clear(cmd_buffer, clear_att, clear_rect);
> - } else {
> - assert(clear_att->aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT |
> - VK_IMAGE_ASPECT_STENCIL_BIT));
> - emit_depthstencil_clear(cmd_buffer, clear_att, clear_rect);
> - }
> -}
> -
> -static bool
> -subpass_needs_clear(const struct anv_cmd_buffer *cmd_buffer)
> -{
> - const struct anv_cmd_state *cmd_state = &cmd_buffer->state;
> - uint32_t ds = cmd_state->subpass->depth_stencil_attachment;
> -
> - for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
> - uint32_t a = cmd_state->subpass->color_attachments[i];
> - if (cmd_state->attachments[a].pending_clear_aspects) {
> - return true;
> - }
> - }
> -
> - if (ds != VK_ATTACHMENT_UNUSED &&
> - cmd_state->attachments[ds].pending_clear_aspects) {
> - return true;
> - }
> -
> - return false;
> -}
> -
> -/**
> - * Emit any pending attachment clears for the current subpass.
> - *
> - * @see anv_attachment_state::pending_clear_aspects
> - */
> -void
> -anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer)
> -{
> - struct anv_cmd_state *cmd_state = &cmd_buffer->state;
> - struct anv_meta_saved_state saved_state;
> -
> - if (!subpass_needs_clear(cmd_buffer))
> - return;
> -
> - meta_clear_begin(&saved_state, cmd_buffer);
> -
> - if (cmd_state->framebuffer->layers > 1)
> - anv_finishme("clearing multi-layer framebuffer");
> -
> - VkClearRect clear_rect = {
> - .rect = cmd_state->render_area,
> - .baseArrayLayer = 0,
> - .layerCount = 1, /* FINISHME: clear multi-layer framebuffer */
> - };
> -
> - for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
> - uint32_t a = cmd_state->subpass->color_attachments[i];
> -
> - if (!cmd_state->attachments[a].pending_clear_aspects)
> - continue;
> -
> - assert(cmd_state->attachments[a].pending_clear_aspects ==
> - VK_IMAGE_ASPECT_COLOR_BIT);
> -
> - VkClearAttachment clear_att = {
> - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
> - .colorAttachment = i, /* Use attachment index relative to subpass */
> - .clearValue = cmd_state->attachments[a].clear_value,
> - };
> -
> - emit_clear(cmd_buffer, &clear_att, &clear_rect);
> - cmd_state->attachments[a].pending_clear_aspects = 0;
> - }
> -
> - uint32_t ds = cmd_state->subpass->depth_stencil_attachment;
> -
> - if (ds != VK_ATTACHMENT_UNUSED &&
> - cmd_state->attachments[ds].pending_clear_aspects) {
> -
> - VkClearAttachment clear_att = {
> - .aspectMask = cmd_state->attachments[ds].pending_clear_aspects,
> - .clearValue = cmd_state->attachments[ds].clear_value,
> - };
> -
> - emit_clear(cmd_buffer, &clear_att, &clear_rect);
> - cmd_state->attachments[ds].pending_clear_aspects = 0;
> - }
> -
> - meta_clear_end(&saved_state, cmd_buffer);
> -}
> --
> 2.5.0.400.gff86faf
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list