From b69dcd8d33f4425228aea97c5f723e6804297c05 Mon Sep 17 00:00:00 2001 From: Ryan Mckeever Date: Tue, 15 Apr 2025 22:56:58 -0700 Subject: [PATCH] panvk: Enable VK_EXT_load_store_op_none Signed-off-by: Ryan Mckeever Reviewed-by: Erik Faye-Lund Reviewed-by: Olivia Lee Part-of: --- docs/features.txt | 4 +- docs/relnotes/new_features.txt | 2 + src/panfrost/vulkan/panvk_physical_device.c | 2 + src/panfrost/vulkan/panvk_vX_cmd_draw.c | 57 ++++++++++++++++----- 4 files changed, 49 insertions(+), 16 deletions(-) diff --git a/docs/features.txt b/docs/features.txt index e7c65a8a37e..aaa50bb4750 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -514,7 +514,7 @@ Vulkan 1.4 -- all DONE: anv, hk, lvp, nvk, radv/gfx8+, tu/a7xx+, vn VK_KHR_global_priority DONE (anv, lvp, nvk, panvk, radv, tu, vn) VK_KHR_index_type_uint8 DONE (anv, lvp, nvk, panvk, pvr, radv, tu, v3dv, vn) VK_KHR_line_rasterization DONE (anv, lvp, nvk, panvk, radv, tu, v3dv, vn) - VK_KHR_load_store_op_none DONE (anv, lvp, nvk, radv, tu, v3dv, vn) + VK_KHR_load_store_op_none DONE (anv, lvp, nvk, panvk, radv, tu, v3dv, vn) VK_KHR_maintenance5 DONE (anv, lvp, nvk, panvk/v10+, radv, tu, v3dv, vn) VK_KHR_maintenance6 DONE (anv, lvp, nvk, radv, tu, vn) VK_KHR_map_memory2 DONE (anv, lvp, nvk, panvk, radv, tu, vn) @@ -625,7 +625,7 @@ Khronos extensions that are not part of any Vulkan version: VK_EXT_index_type_uint8 DONE (anv, hasvk, hk, nvk, lvp, panvk, pvr, radv/gfx8+, tu, v3dv, vn) VK_EXT_legacy_vertex_attributes DONE (anv, lvp, nvk, radv, tu, vn) VK_EXT_line_rasterization DONE (anv, hasvk, hk, nvk, panvk, lvp, radv, tu, v3dv, vn) - VK_EXT_load_store_op_none DONE (anv, hk, nvk, radv, tu, v3dv, vn) + VK_EXT_load_store_op_none DONE (anv, hk, nvk, panvk, radv, tu, v3dv, vn) VK_EXT_memory_budget DONE (anv, hasvk, lvp, nvk, pvr, radv, tu, v3dv, vn) VK_EXT_memory_priority DONE (lvp, radv) VK_EXT_mesh_shader DONE (anv/gfx12.5+, lvp, radv) diff --git a/docs/relnotes/new_features.txt b/docs/relnotes/new_features.txt index 4f603d80f50..6184503220b 100644 --- a/docs/relnotes/new_features.txt +++ b/docs/relnotes/new_features.txt @@ -32,3 +32,5 @@ Completed OpenCL 2.0 coarse grain buffer SVM support VK_EXT_shader_subgroup_ballot on panvk VK_EXT_shader_subgroup_vote on panvk Vulkan video support on GFX12 (RDNA4) for RADV +VK_KHR_load_store_op_none on panvk +VK_EXT_load_store_op_none on panvk diff --git a/src/panfrost/vulkan/panvk_physical_device.c b/src/panfrost/vulkan/panvk_physical_device.c index 51e6b8cb3ee..4edd60faa34 100644 --- a/src/panfrost/vulkan/panvk_physical_device.c +++ b/src/panfrost/vulkan/panvk_physical_device.c @@ -240,6 +240,7 @@ get_device_extensions(const struct panvk_physical_device *device, .KHR_imageless_framebuffer = true, .KHR_index_type_uint8 = true, .KHR_line_rasterization = true, + .KHR_load_store_op_none = true, .KHR_maintenance1 = true, .KHR_maintenance2 = true, .KHR_maintenance3 = true, @@ -302,6 +303,7 @@ get_device_extensions(const struct panvk_physical_device *device, .EXT_image_robustness = true, .EXT_index_type_uint8 = true, .EXT_line_rasterization = true, + .EXT_load_store_op_none = true, .EXT_physical_device_drm = true, .EXT_pipeline_creation_cache_control = true, .EXT_pipeline_creation_feedback = true, diff --git a/src/panfrost/vulkan/panvk_vX_cmd_draw.c b/src/panfrost/vulkan/panvk_vX_cmd_draw.c index 85fe4bdd5dd..fd29c6fa7ca 100644 --- a/src/panfrost/vulkan/panvk_vX_cmd_draw.c +++ b/src/panfrost/vulkan/panvk_vX_cmd_draw.c @@ -13,6 +13,40 @@ #include "pan_desc.h" #include "pan_util.h" +static void +att_set_clear_preload(const VkRenderingAttachmentInfo *att, bool *clear, bool *preload) +{ + switch (att->loadOp) { + case VK_ATTACHMENT_LOAD_OP_CLEAR: + *clear = true; + break; + case VK_ATTACHMENT_LOAD_OP_LOAD: + *preload = true; + break; + case VK_ATTACHMENT_LOAD_OP_NONE: + break; + case VK_ATTACHMENT_LOAD_OP_DONT_CARE: + /* This is a very frustrating corner case. From the spec: + * + * VK_ATTACHMENT_STORE_OP_NONE specifies the contents within the + * render area are not accessed by the store operation as long as + * no values are written to the attachment during the render pass. + * + * With VK_ATTACHMENT_LOAD_OP_DONT_CARE + VK_ATTACHMENT_STORE_OP_NONE, + * we need to preserve the contents throughout partial renders. The + * easiest way to do that is forcing a preload, so that partial stores + * for unused attachments will be no-op'd by writing existing contents. + * + * TODO: disable preload when we have clean_pixel_write_enable = false + * as an optimization + */ + *preload |= att->storeOp == VK_ATTACHMENT_STORE_OP_NONE; + break; + default: + unreachable("Unsupported loadOp"); + } +} + static void render_state_set_color_attachment(struct panvk_cmd_buffer *cmdbuf, const VkRenderingAttachmentInfo *att, @@ -45,14 +79,13 @@ render_state_set_color_attachment(struct panvk_cmd_buffer *cmdbuf, enum pipe_format fmt = vk_format_to_pipe_format(iview->vk.format); union pipe_color_union *col = (union pipe_color_union *)&att->clearValue.color; - - fbinfo->rts[index].clear = true; pan_pack_color(phys_dev->formats.blendable, fbinfo->rts[index].clear_value, col, fmt, false); - } else if (att->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD) { - fbinfo->rts[index].preload = true; } + att_set_clear_preload(att, &fbinfo->rts[index].clear, + &fbinfo->rts[index].preload); + if (att->resolveMode != VK_RESOLVE_MODE_NONE) { struct panvk_resolve_attachment *resolve_info = &state->render.color_attachments.resolve[index]; @@ -109,12 +142,10 @@ render_state_set_z_attachment(struct panvk_cmd_buffer *cmdbuf, vk_format_to_pipe_format(vk_format_depth_only(img->vk.format)); } - if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { - fbinfo->zs.clear.z = true; + if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) fbinfo->zs.clear_value.depth = att->clearValue.depthStencil.depth; - } else if (att->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD) { - fbinfo->zs.preload.z = true; - } + + att_set_clear_preload(att, &fbinfo->zs.clear.z, &fbinfo->zs.preload.z); if (att->resolveMode != VK_RESOLVE_MODE_NONE) { struct panvk_resolve_attachment *resolve_info = @@ -188,12 +219,10 @@ render_state_set_s_attachment(struct panvk_cmd_buffer *cmdbuf, fbinfo->zs.view.s = NULL; } - if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) { - fbinfo->zs.clear.s = true; + if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) fbinfo->zs.clear_value.stencil = att->clearValue.depthStencil.stencil; - } else if (att->loadOp == VK_ATTACHMENT_LOAD_OP_LOAD) { - fbinfo->zs.preload.s = true; - } + + att_set_clear_preload(att, &fbinfo->zs.clear.s, &fbinfo->zs.preload.s); if (att->resolveMode != VK_RESOLVE_MODE_NONE) { struct panvk_resolve_attachment *resolve_info =