On Fri, Oct 07, 2016 at 09:41:16PM -0700, Jason Ekstrand wrote: > Signed-off-by: Jason Ekstrand <ja...@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.pohjolai...@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@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev