X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Famd%2Fvulkan%2Fradv_meta_clear.c;h=b42ecedfc9809d15ad5ffb14986e203987e9a2ee;hb=258ebe79a0c2133e362035b76f3cf3243880926f;hp=7ca4bc3492006174cbab1932901c93eb10c77733;hpb=af62984c8a76a039d182f2929f3741925d129ec3;p=mesa.git diff --git a/src/amd/vulkan/radv_meta_clear.c b/src/amd/vulkan/radv_meta_clear.c index 7ca4bc34920..b42ecedfc98 100644 --- a/src/amd/vulkan/radv_meta_clear.c +++ b/src/amd/vulkan/radv_meta_clear.c @@ -296,26 +296,26 @@ radv_device_finish_meta_clear_state(struct radv_device *device) for (uint32_t j = 0; j < ARRAY_SIZE(state->clear[i].color_pipelines); ++j) { radv_DestroyPipeline(radv_device_to_handle(device), state->clear[i].color_pipelines[j], - &device->meta_state.alloc); + &state->alloc); radv_DestroyRenderPass(radv_device_to_handle(device), state->clear[i].render_pass[j], - &device->meta_state.alloc); + &state->alloc); } for (uint32_t j = 0; j < NUM_DEPTH_CLEAR_PIPELINES; j++) { radv_DestroyPipeline(radv_device_to_handle(device), state->clear[i].depth_only_pipeline[j], - &device->meta_state.alloc); + &state->alloc); radv_DestroyPipeline(radv_device_to_handle(device), state->clear[i].stencil_only_pipeline[j], - &device->meta_state.alloc); + &state->alloc); radv_DestroyPipeline(radv_device_to_handle(device), state->clear[i].depthstencil_pipeline[j], - &device->meta_state.alloc); + &state->alloc); } radv_DestroyRenderPass(radv_device_to_handle(device), state->clear[i].depthstencil_rp, - &device->meta_state.alloc); + &state->alloc); } radv_DestroyPipelineLayout(radv_device_to_handle(device), state->clear_color_p_layout, @@ -374,10 +374,8 @@ emit_color_clear(struct radv_cmd_buffer *cmd_buffer, radv_cmd_buffer_set_subpass(cmd_buffer, &clear_subpass, false); - if (cmd_buffer->state.pipeline != radv_pipeline_from_handle(pipeline)) { - radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS, - pipeline); - } + radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS, + pipeline); radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkViewport) { .x = clear_rect->rect.offset.x, @@ -543,8 +541,10 @@ create_depthstencil_pipeline(struct radv_device *device, static bool depth_view_can_fast_clear(struct radv_cmd_buffer *cmd_buffer, const struct radv_image_view *iview, + VkImageAspectFlags aspects, VkImageLayout layout, - const VkClearRect *clear_rect) + const VkClearRect *clear_rect, + VkClearDepthStencilValue clear_value) { uint32_t queue_mask = radv_image_queue_family_mask(iview->image, cmd_buffer->queue_family_index, @@ -553,6 +553,11 @@ static bool depth_view_can_fast_clear(struct radv_cmd_buffer *cmd_buffer, clear_rect->rect.extent.width != iview->extent.width || clear_rect->rect.extent.height != iview->extent.height) return false; + if (iview->image->tc_compatible_htile && + (((aspects & VK_IMAGE_ASPECT_DEPTH_BIT) && clear_value.depth != 0.0 && + clear_value.depth != 1.0) || + ((aspects & VK_IMAGE_ASPECT_STENCIL_BIT) && clear_value.stencil != 0))) + return false; if (iview->image->surface.htile_size && iview->base_mip == 0 && iview->base_layer == 0 && @@ -572,7 +577,7 @@ pick_depthstencil_pipeline(struct radv_cmd_buffer *cmd_buffer, const VkClearRect *clear_rect, VkClearDepthStencilValue clear_value) { - bool fast = depth_view_can_fast_clear(cmd_buffer, iview, layout, clear_rect); + bool fast = depth_view_can_fast_clear(cmd_buffer, iview, aspects, layout, clear_rect, clear_value); int index = DEPTH_CLEAR_SLOW; if (fast) { @@ -609,10 +614,6 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer, const uint32_t samples_log2 = ffs(samples) - 1; VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer); - 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); if (!(aspects & VK_IMAGE_ASPECT_DEPTH_BIT)) @@ -637,12 +638,12 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer, clear_rect, clear_value); - if (cmd_buffer->state.pipeline != radv_pipeline_from_handle(pipeline)) { - radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS, - pipeline); - } + radv_CmdBindPipeline(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS, + pipeline); - if (depth_view_can_fast_clear(cmd_buffer, iview, subpass->depth_stencil_attachment.layout, clear_rect)) + if (depth_view_can_fast_clear(cmd_buffer, iview, aspects, + subpass->depth_stencil_attachment.layout, + clear_rect, clear_value)) radv_set_depth_clear_regs(cmd_buffer, iview->image, clear_value, aspects); radv_CmdSetViewport(radv_cmd_buffer_to_handle(cmd_buffer), 0, 1, &(VkViewport) { @@ -673,12 +674,12 @@ emit_fast_htile_clear(struct radv_cmd_buffer *cmd_buffer, const struct radv_image_view *iview = fb->attachments[pass_att].attachment; VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil; VkImageAspectFlags aspects = clear_att->aspectMask; - uint32_t clear_word; + uint32_t clear_word, flush_bits; if (!iview->image->surface.htile_size) return false; - if (cmd_buffer->device->debug_flags & RADV_DEBUG_NO_FAST_CLEARS) + if (cmd_buffer->device->instance->debug_flags & RADV_DEBUG_NO_FAST_CLEARS) return false; if (!radv_layout_is_htile_compressed(iview->image, image_layout, radv_image_queue_family_mask(iview->image, cmd_buffer->queue_family_index, cmd_buffer->queue_family_index))) @@ -694,9 +695,6 @@ emit_fast_htile_clear(struct radv_cmd_buffer *cmd_buffer, if (iview->image->info.array_size != iview->layer_count) goto fail; - if (iview->image->info.levels > 1) - goto fail; - if (!radv_image_extent_compare(iview->image, &iview->extent)) goto fail; @@ -728,20 +726,17 @@ emit_fast_htile_clear(struct radv_cmd_buffer *cmd_buffer, cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_FLUSH_AND_INV_DB | RADV_CMD_FLAG_FLUSH_AND_INV_DB_META; - radv_fill_buffer(cmd_buffer, iview->image->bo, - iview->image->offset + iview->image->htile_offset, - iview->image->surface.htile_size, clear_word); - + flush_bits = radv_fill_buffer(cmd_buffer, iview->image->bo, + iview->image->offset + iview->image->htile_offset, + iview->image->surface.htile_size, clear_word); radv_set_depth_clear_regs(cmd_buffer, iview->image, clear_value, aspects); - if (post_flush) - *post_flush |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH | - RADV_CMD_FLAG_INV_VMEM_L1 | - RADV_CMD_FLAG_WRITEBACK_GLOBAL_L2; - else - cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH | - RADV_CMD_FLAG_INV_VMEM_L1 | - RADV_CMD_FLAG_WRITEBACK_GLOBAL_L2; + if (post_flush) { + *post_flush |= flush_bits; + } else { + cmd_buffer->state.flush_bits |= flush_bits; + } + return true; fail: return false; @@ -768,8 +763,6 @@ radv_device_init_meta_clear_state(struct radv_device *device) VkResult res; struct radv_meta_state *state = &device->meta_state; - memset(&device->meta_state.clear, 0, sizeof(device->meta_state.clear)); - VkPipelineLayoutCreateInfo pl_color_create_info = { .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, .setLayoutCount = 0, @@ -952,13 +945,13 @@ emit_fast_color_clear(struct radv_cmd_buffer *cmd_buffer, const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer; const struct radv_image_view *iview = fb->attachments[pass_att].attachment; VkClearColorValue clear_value = clear_att->clearValue.color; - uint32_t clear_color[2]; + uint32_t clear_color[2], flush_bits; bool ret; if (!iview->image->cmask.size && !iview->image->surface.dcc_size) return false; - if (cmd_buffer->device->debug_flags & RADV_DEBUG_NO_FAST_CLEARS) + if (cmd_buffer->device->instance->debug_flags & RADV_DEBUG_NO_FAST_CLEARS) return false; if (!radv_layout_can_fast_clear(iview->image, image_layout, radv_image_queue_family_mask(iview->image, cmd_buffer->queue_family_index, cmd_buffer->queue_family_index))) @@ -1021,30 +1014,22 @@ emit_fast_color_clear(struct radv_cmd_buffer *cmd_buffer, &clear_value, &reset_value, &can_avoid_fast_clear_elim); - radv_fill_buffer(cmd_buffer, iview->image->bo, - iview->image->offset + iview->image->dcc_offset, - iview->image->surface.dcc_size, reset_value); + flush_bits = radv_fill_buffer(cmd_buffer, iview->image->bo, + iview->image->offset + iview->image->dcc_offset, + iview->image->surface.dcc_size, reset_value); radv_set_dcc_need_cmask_elim_pred(cmd_buffer, iview->image, !can_avoid_fast_clear_elim); } else { - - if (iview->image->surface.bpe > 8) { - /* 128 bit formats not supported */ - return false; - } - radv_fill_buffer(cmd_buffer, iview->image->bo, - iview->image->offset + iview->image->cmask.offset, - iview->image->cmask.size, 0); + flush_bits = radv_fill_buffer(cmd_buffer, iview->image->bo, + iview->image->offset + iview->image->cmask.offset, + iview->image->cmask.size, 0); } - if (post_flush) - *post_flush |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH | - RADV_CMD_FLAG_INV_VMEM_L1 | - RADV_CMD_FLAG_WRITEBACK_GLOBAL_L2; - else - cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH | - RADV_CMD_FLAG_INV_VMEM_L1 | - RADV_CMD_FLAG_WRITEBACK_GLOBAL_L2; + if (post_flush) { + *post_flush |= flush_bits; + } else { + cmd_buffer->state.flush_bits |= flush_bits; + } radv_set_color_clear_regs(cmd_buffer, iview->image, subpass_att, clear_color); @@ -1077,32 +1062,56 @@ emit_clear(struct radv_cmd_buffer *cmd_buffer, } } +static inline bool +radv_attachment_needs_clear(struct radv_cmd_state *cmd_state, uint32_t a) +{ + uint32_t view_mask = cmd_state->subpass->view_mask; + return (a != VK_ATTACHMENT_UNUSED && + cmd_state->attachments[a].pending_clear_aspects && + (!view_mask || (view_mask & ~cmd_state->attachments[a].cleared_views))); +} + static bool -subpass_needs_clear(const struct radv_cmd_buffer *cmd_buffer) +radv_subpass_needs_clear(struct radv_cmd_buffer *cmd_buffer) { - const struct radv_cmd_state *cmd_state = &cmd_buffer->state; - uint32_t ds; + struct radv_cmd_state *cmd_state = &cmd_buffer->state; + uint32_t a; if (!cmd_state->subpass) return false; - uint32_t view_mask = cmd_state->subpass->view_mask; - ds = cmd_state->subpass->depth_stencil_attachment.attachment; + for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) { - uint32_t a = cmd_state->subpass->color_attachments[i].attachment; - if (a != VK_ATTACHMENT_UNUSED && - cmd_state->attachments[a].pending_clear_aspects && - (!view_mask || (view_mask & ~cmd_state->attachments[a].cleared_views))) { + a = cmd_state->subpass->color_attachments[i].attachment; + if (radv_attachment_needs_clear(cmd_state, a)) return true; - } } - if (ds != VK_ATTACHMENT_UNUSED && - cmd_state->attachments[ds].pending_clear_aspects && - (!view_mask || (view_mask & ~cmd_state->attachments[ds].cleared_views))) { - return true; - } + a = cmd_state->subpass->depth_stencil_attachment.attachment; + return radv_attachment_needs_clear(cmd_state, a); +} - return false; +static void +radv_subpass_clear_attachment(struct radv_cmd_buffer *cmd_buffer, + struct radv_attachment_state *attachment, + const VkClearAttachment *clear_att, + enum radv_cmd_flush_bits *pre_flush, + enum radv_cmd_flush_bits *post_flush) +{ + struct radv_cmd_state *cmd_state = &cmd_buffer->state; + uint32_t view_mask = cmd_state->subpass->view_mask; + + VkClearRect clear_rect = { + .rect = cmd_state->render_area, + .baseArrayLayer = 0, + .layerCount = cmd_state->framebuffer->layers, + }; + + emit_clear(cmd_buffer, clear_att, &clear_rect, pre_flush, post_flush, + view_mask & ~attachment->cleared_views); + if (view_mask) + attachment->cleared_views |= view_mask; + else + attachment->pending_clear_aspects = 0; } /** @@ -1117,25 +1126,18 @@ radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer *cmd_buffer) struct radv_meta_saved_state saved_state; enum radv_cmd_flush_bits pre_flush = 0; enum radv_cmd_flush_bits post_flush = 0; - uint32_t view_mask = cmd_buffer->state.subpass->view_mask; - if (!subpass_needs_clear(cmd_buffer)) + if (!radv_subpass_needs_clear(cmd_buffer)) return; - radv_meta_save_graphics_reset_vport_scissor_novertex(&saved_state, cmd_buffer); - - VkClearRect clear_rect = { - .rect = cmd_state->render_area, - .baseArrayLayer = 0, - .layerCount = cmd_state->framebuffer->layers, - }; + radv_meta_save(&saved_state, cmd_buffer, + RADV_META_SAVE_GRAPHICS_PIPELINE | + RADV_META_SAVE_CONSTANTS); for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) { uint32_t a = cmd_state->subpass->color_attachments[i].attachment; - if (a == VK_ATTACHMENT_UNUSED || - !cmd_state->attachments[a].pending_clear_aspects || - (view_mask && !(view_mask & ~cmd_state->attachments[a].cleared_views))) + if (!radv_attachment_needs_clear(cmd_state, a)) continue; assert(cmd_state->attachments[a].pending_clear_aspects == @@ -1147,34 +1149,23 @@ radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer *cmd_buffer) .clearValue = cmd_state->attachments[a].clear_value, }; - emit_clear(cmd_buffer, &clear_att, &clear_rect, &pre_flush, &post_flush, - view_mask & ~cmd_state->attachments[a].cleared_views); - if (view_mask) - cmd_state->attachments[a].cleared_views |= view_mask; - else - cmd_state->attachments[a].pending_clear_aspects = 0; + radv_subpass_clear_attachment(cmd_buffer, + &cmd_state->attachments[a], + &clear_att, &pre_flush, + &post_flush); } uint32_t ds = cmd_state->subpass->depth_stencil_attachment.attachment; + if (radv_attachment_needs_clear(cmd_state, ds)) { + VkClearAttachment clear_att = { + .aspectMask = cmd_state->attachments[ds].pending_clear_aspects, + .clearValue = cmd_state->attachments[ds].clear_value, + }; - if (ds != VK_ATTACHMENT_UNUSED) { - - if (cmd_state->attachments[ds].pending_clear_aspects && - (!view_mask || (view_mask & ~cmd_state->attachments[ds].cleared_views))) { - - 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, - &pre_flush, &post_flush, - view_mask & ~cmd_state->attachments[ds].cleared_views); - if (view_mask) - cmd_state->attachments[ds].cleared_views |= view_mask; - else - cmd_state->attachments[ds].pending_clear_aspects = 0; - } + radv_subpass_clear_attachment(cmd_buffer, + &cmd_state->attachments[ds], + &clear_att, &pre_flush, + &post_flush); } radv_meta_restore(&saved_state, cmd_buffer); @@ -1362,11 +1353,6 @@ radv_cmd_clear_image(struct radv_cmd_buffer *cmd_buffer, } } -union meta_saved_state { - struct radv_meta_saved_state gfx; - struct radv_meta_saved_compute_state compute; -}; - void radv_CmdClearColorImage( VkCommandBuffer commandBuffer, VkImage image_h, @@ -1377,22 +1363,25 @@ void radv_CmdClearColorImage( { RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); RADV_FROM_HANDLE(radv_image, image, image_h); - union meta_saved_state saved_state; + struct radv_meta_saved_state saved_state; bool cs = cmd_buffer->queue_family_index == RADV_QUEUE_COMPUTE; - if (cs) - radv_meta_save_compute(&saved_state.compute, cmd_buffer, 16); - else - radv_meta_save_graphics_reset_vport_scissor_novertex(&saved_state.gfx, cmd_buffer); + if (cs) { + radv_meta_save(&saved_state, cmd_buffer, + RADV_META_SAVE_COMPUTE_PIPELINE | + RADV_META_SAVE_CONSTANTS | + RADV_META_SAVE_DESCRIPTORS); + } else { + radv_meta_save(&saved_state, cmd_buffer, + RADV_META_SAVE_GRAPHICS_PIPELINE | + RADV_META_SAVE_CONSTANTS); + } radv_cmd_clear_image(cmd_buffer, image, imageLayout, (const VkClearValue *) pColor, rangeCount, pRanges, cs); - if (cs) - radv_meta_restore_compute(&saved_state.compute, cmd_buffer); - else - radv_meta_restore(&saved_state.gfx, cmd_buffer); + radv_meta_restore(&saved_state, cmd_buffer); } void radv_CmdClearDepthStencilImage( @@ -1407,7 +1396,9 @@ void radv_CmdClearDepthStencilImage( RADV_FROM_HANDLE(radv_image, image, image_h); struct radv_meta_saved_state saved_state; - radv_meta_save_graphics_reset_vport_scissor_novertex(&saved_state, cmd_buffer); + radv_meta_save(&saved_state, cmd_buffer, + RADV_META_SAVE_GRAPHICS_PIPELINE | + RADV_META_SAVE_CONSTANTS); radv_cmd_clear_image(cmd_buffer, image, imageLayout, (const VkClearValue *) pDepthStencil, @@ -1431,7 +1422,9 @@ void radv_CmdClearAttachments( if (!cmd_buffer->state.subpass) return; - radv_meta_save_graphics_reset_vport_scissor_novertex(&saved_state, cmd_buffer); + radv_meta_save(&saved_state, cmd_buffer, + RADV_META_SAVE_GRAPHICS_PIPELINE | + RADV_META_SAVE_CONSTANTS); /* FINISHME: We can do better than this dumb loop. It thrashes too much * state.