Module: Mesa
Branch: main
Commit: a02d1cfa9e999c513c5b9544695c77966ebbae7d
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=a02d1cfa9e999c513c5b9544695c77966ebbae7d

Author: Connor Abbott <[email protected]>
Date:   Fri May 26 15:51:50 2023 +0200

vk/graphics_state: Support VK_EXT_attachment_feedback_loop_dynamic_state

Reviewed-by: Lionel Landwerlin <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25436>

---

 src/vulkan/runtime/vk_graphics_state.c | 60 ++++++++++++++++++++++++++++++++--
 src/vulkan/runtime/vk_graphics_state.h |  3 ++
 2 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/src/vulkan/runtime/vk_graphics_state.c 
b/src/vulkan/runtime/vk_graphics_state.c
index 9888bd92bf4..eb6f22a9b6f 100644
--- a/src/vulkan/runtime/vk_graphics_state.c
+++ b/src/vulkan/runtime/vk_graphics_state.c
@@ -124,6 +124,9 @@ get_dynamic_state_groups(BITSET_WORD *dynamic,
       BITSET_SET(dynamic, MESA_VK_DYNAMIC_CB_WRITE_MASKS);
       BITSET_SET(dynamic, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS);
    }
+
+   if (groups & MESA_VK_GRAPHICS_STATE_RENDER_PASS_BIT)
+      BITSET_SET(dynamic, MESA_VK_DYNAMIC_ATTACHMENT_FEEDBACK_LOOP_ENABLE);
 }
 
 static enum mesa_vk_graphics_state_groups
@@ -1037,22 +1040,32 @@ vk_pipeline_flags_init(struct 
vk_graphics_pipeline_state *state,
                        VkPipelineCreateFlags2KHR driver_rp_flags,
                        bool has_driver_rp,
                        const VkGraphicsPipelineCreateInfo *info,
+                       const BITSET_WORD *dynamic,
                        VkGraphicsPipelineLibraryFlagsEXT lib)
 {
    VkPipelineCreateFlags2KHR valid_pipeline_flags = 0;
+   VkPipelineCreateFlags2KHR valid_renderpass_flags = 0;
    if (lib & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) {
+      valid_renderpass_flags |=
+         
VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR |
+         
VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT;
       valid_pipeline_flags |=
          
VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR |
          
VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT;
    }
    if (lib & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT) {
-      valid_pipeline_flags |=
+      valid_renderpass_flags |=
          VK_PIPELINE_CREATE_2_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT |
          VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
+      if (!IS_DYNAMIC(ATTACHMENT_FEEDBACK_LOOP_ENABLE)) {
+         valid_pipeline_flags |=
+            VK_PIPELINE_CREATE_2_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT |
+            
VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
+      }
    }
    const VkPipelineCreateFlags2KHR renderpass_flags =
       (has_driver_rp ? driver_rp_flags :
-       vk_get_pipeline_rendering_flags(info)) & valid_pipeline_flags;
+       vk_get_pipeline_rendering_flags(info)) & valid_renderpass_flags;
 
    const VkPipelineCreateFlags2KHR pipeline_flags =
       vk_graphics_pipeline_create_flags(info) & valid_pipeline_flags;
@@ -1385,7 +1398,7 @@ vk_graphics_pipeline_state_fill(const struct vk_device 
*device,
 
    if (lib & (VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT |
               VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT)) 
{
-      vk_pipeline_flags_init(state, driver_rp_flags, !!driver_rp, info, lib);
+      vk_pipeline_flags_init(state, driver_rp_flags, !!driver_rp, info, 
dynamic, lib);
    }
 
    if (lib & VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT) {
@@ -1495,6 +1508,22 @@ vk_graphics_pipeline_state_fill(const struct vk_device 
*device,
    /* Filter dynamic state down to just what we're adding */
    BITSET_DECLARE(dynamic_filter, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);
    get_dynamic_state_groups(dynamic_filter, needs);
+
+   /* Attachment feedback loop state is part of the renderpass state in mesa
+    * because attachment feedback loops can also come from the render pass,
+    * but in Vulkan it is part of the fragment output interface. The
+    * renderpass state also exists, possibly in an incomplete state, in other
+    * stages for things like the view mask, but it does not contain the
+    * feedback loop flags. In those other stages we have to ignore
+    * VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT, even though it is
+    * part of a state group that exists in those stages.
+    */
+   if (!(lib &
+         VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT)) {
+      BITSET_CLEAR(dynamic_filter,
+                   MESA_VK_DYNAMIC_ATTACHMENT_FEEDBACK_LOOP_ENABLE);
+   }
+
    BITSET_AND(dynamic, dynamic, dynamic_filter);
 
    /* And add it in */
@@ -1826,6 +1855,18 @@ vk_dynamic_graphics_state_fill(struct 
vk_dynamic_graphics_state *dyn,
 
 #undef INIT_DYNAMIC_STATE
 
+   /* Feedback loop state is weird: implicit feedback loops from the
+    * renderpass and dynamically-enabled feedback loops can in theory both be
+    * enabled independently, so we can't just use one field; instead drivers
+    * have to OR the pipeline state (in vk_render_pass_state::pipeline_flags)
+    * and dynamic state. Due to this it isn't worth tracking
+    * implicit render pass flags vs. pipeline flags in the pipeline state, and
+    * we just combine the two in vk_render_pass_flags_init() and don't bother
+    * setting the dynamic state from the pipeline here, instead just making
+    * sure the dynamic state is reset to 0 when feedback loop state is static.
+    */
+   dyn->feedback_loops = 0;
+
    get_dynamic_state_groups(dyn->set, groups);
 
    /* Vertex input state is always included in a complete pipeline. If p->vi
@@ -2050,6 +2091,8 @@ vk_dynamic_graphics_state_copy(struct 
vk_dynamic_graphics_state *dst,
    if (IS_SET_IN_SRC(CB_BLEND_CONSTANTS))
       COPY_ARRAY(CB_BLEND_CONSTANTS, cb.blend_constants, 4);
 
+   COPY_IF_SET(ATTACHMENT_FEEDBACK_LOOP_ENABLE, feedback_loops);
+
 #undef IS_SET_IN_SRC
 #undef MARK_DIRTY
 #undef COPY_MEMBER
@@ -2362,6 +2405,17 @@ vk_common_CmdSetProvokingVertexModeEXT(VkCommandBuffer 
commandBuffer,
                  rs.provoking_vertex, provokingVertexMode);
 }
 
+VKAPI_ATTR void VKAPI_CALL
+vk_common_CmdSetAttachmentFeedbackLoopEnableEXT(VkCommandBuffer commandBuffer,
+                                                VkImageAspectFlags aspectMask)
+{
+   VK_FROM_HANDLE(vk_command_buffer, cmd, commandBuffer);
+   struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
+
+   SET_DYN_VALUE(dyn, ATTACHMENT_FEEDBACK_LOOP_ENABLE,
+                 feedback_loops, aspectMask);
+}
+
 VKAPI_ATTR void VKAPI_CALL
 vk_common_CmdSetRasterizationStreamEXT(VkCommandBuffer commandBuffer,
                                        uint32_t rasterizationStream)
diff --git a/src/vulkan/runtime/vk_graphics_state.h 
b/src/vulkan/runtime/vk_graphics_state.h
index 392ef9f5277..c56366a9fbf 100644
--- a/src/vulkan/runtime/vk_graphics_state.h
+++ b/src/vulkan/runtime/vk_graphics_state.h
@@ -818,6 +818,9 @@ struct vk_dynamic_graphics_state {
    /** Color blend state */
    struct vk_color_blend_state cb;
 
+   /** MESA_VK_DYNAMIC_ATTACHMENT_FEEDBACK_LOOP_ENABLE */
+   VkImageAspectFlags feedback_loops;
+
    /** For pipelines, which bits of dynamic state are set */
    BITSET_DECLARE(set, MESA_VK_DYNAMIC_GRAPHICS_STATE_ENUM_MAX);
 

Reply via email to