diff --git a/src/amd/vulkan/radv_pipeline_graphics.c b/src/amd/vulkan/radv_pipeline_graphics.c index 4aa32bec6bc..8f458ce46ce 100644 --- a/src/amd/vulkan/radv_pipeline_graphics.c +++ b/src/amd/vulkan/radv_pipeline_graphics.c @@ -298,7 +298,7 @@ radv_pipeline_uses_vrs_attachment(const struct radv_graphics_pipeline *pipeline, { VkPipelineCreateFlags2KHR create_flags = pipeline->base.create_flags; if (state->rp) - create_flags |= state->rp->pipeline_flags; + create_flags |= state->pipeline_flags; return (create_flags & VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR) != 0; } @@ -697,7 +697,7 @@ radv_pipeline_import_graphics_info(struct radv_device *device, struct radv_graph pipeline->active_stages |= sinfo->stage; } - result = vk_graphics_pipeline_state_fill(&device->vk, state, pCreateInfo, NULL, NULL, NULL, + result = vk_graphics_pipeline_state_fill(&device->vk, state, pCreateInfo, NULL, 0, NULL, NULL, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT, &pipeline->state_data); if (result != VK_SUCCESS) return result; @@ -821,7 +821,7 @@ radv_pipeline_uses_ds_feedback_loop(const struct radv_graphics_pipeline *pipelin { VkPipelineCreateFlags2KHR create_flags = pipeline->base.create_flags; if (state->rp) - create_flags |= state->rp->pipeline_flags; + create_flags |= state->pipeline_flags; return (create_flags & VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT) != 0; } diff --git a/src/freedreno/vulkan/tu_pipeline.cc b/src/freedreno/vulkan/tu_pipeline.cc index 707d35ae585..79fe07d082b 100644 --- a/src/freedreno/vulkan/tu_pipeline.cc +++ b/src/freedreno/vulkan/tu_pipeline.cc @@ -3774,7 +3774,7 @@ tu_pipeline_builder_parse_rasterization_order( * setting the SINGLE_PRIM_MODE field to the same value that the blob does * for advanced_blend in sysmem mode if a feedback loop is detected. */ - if (builder->graphics_state.rp->pipeline_flags & + if (builder->graphics_state.pipeline_flags & (VK_PIPELINE_CREATE_2_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT | VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT)) { sysmem_prim_mode = FLUSH_PER_OVERLAP_AND_OVERWRITE; @@ -3966,15 +3966,13 @@ tu_pipeline_builder_build(struct tu_pipeline_builder *builder, vk_dynamic_graphics_state_fill(&gfx_pipeline->dynamic_state, &builder->graphics_state); gfx_pipeline->feedback_loop_color = - (builder->graphics_state.rp->pipeline_flags & + (builder->graphics_state.pipeline_flags & VK_PIPELINE_CREATE_2_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT); gfx_pipeline->feedback_loop_ds = - (builder->graphics_state.rp->pipeline_flags & + (builder->graphics_state.pipeline_flags & VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT); gfx_pipeline->feedback_loop_may_involve_textures = - (gfx_pipeline->feedback_loop_color || - gfx_pipeline->feedback_loop_ds) && - !builder->graphics_state.rp->feedback_loop_input_only; + builder->graphics_state.feedback_loop_not_input_only; } return VK_SUCCESS; @@ -3993,7 +3991,6 @@ tu_fill_render_pass_state(struct vk_render_pass_state *rp, { rp->view_mask = subpass->multiview_mask; rp->color_attachment_count = subpass->color_count; - rp->pipeline_flags = 0; const uint32_t a = subpass->depth_stencil_attachment.attachment; rp->depth_attachment_format = VK_FORMAT_UNDEFINED; @@ -4094,6 +4091,7 @@ tu_pipeline_builder_init_graphics( struct vk_render_pass_state rp_state = {}; const struct vk_render_pass_state *driver_rp = NULL; + VkPipelineCreateFlags2KHR rp_flags = 0; builder->unscaled_input_fragcoord = 0; @@ -4114,8 +4112,6 @@ tu_pipeline_builder_init_graphics( tu_fill_render_pass_state(&rp_state, pass, subpass); - rp_state.feedback_loop_input_only = true; - for (unsigned i = 0; i < subpass->input_count; i++) { /* Input attachments stored in GMEM must be loaded with unscaled * FragCoord. @@ -4124,29 +4120,18 @@ tu_pipeline_builder_init_graphics( builder->unscaled_input_fragcoord |= 1u << i; } - /* Feedback loop flags can come from either the user (in which case they - * may involve textures) or from the driver (in which case they don't). - */ - VkPipelineCreateFlags feedback_flags = builder->create_flags & - (VK_PIPELINE_CREATE_2_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT | - VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT); - if (feedback_flags) { - rp_state.feedback_loop_input_only = false; - rp_state.pipeline_flags |= feedback_flags; - } - if (subpass->feedback_loop_color) { - rp_state.pipeline_flags |= + rp_flags |= VK_PIPELINE_CREATE_2_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; } if (subpass->feedback_loop_ds) { - rp_state.pipeline_flags |= + rp_flags |= VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; } if (pass->fragment_density_map.attachment != VK_ATTACHMENT_UNUSED) { - rp_state.pipeline_flags |= + rp_flags |= VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT; } @@ -4166,12 +4151,13 @@ tu_pipeline_builder_init_graphics( &builder->graphics_state, builder->create_info, driver_rp, + rp_flags, &builder->all_state, NULL, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT, NULL); if (builder->graphics_state.rp) { - builder->fragment_density_map = (builder->graphics_state.rp->pipeline_flags & + builder->fragment_density_map = (builder->graphics_state.pipeline_flags & VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT) || TU_DEBUG(FDM); } diff --git a/src/gallium/frontends/lavapipe/lvp_pipeline.c b/src/gallium/frontends/lavapipe/lvp_pipeline.c index dc228357b39..d8ac16aa9a4 100644 --- a/src/gallium/frontends/lavapipe/lvp_pipeline.c +++ b/src/gallium/frontends/lavapipe/lvp_pipeline.c @@ -853,7 +853,7 @@ lvp_graphics_pipeline_init(struct lvp_pipeline *pipeline, result = vk_graphics_pipeline_state_fill(&device->vk, &pipeline->graphics_state, - pCreateInfo, NULL, NULL, NULL, + pCreateInfo, NULL, 0, NULL, NULL, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT, &pipeline->state_data); if (result != VK_SUCCESS) diff --git a/src/imagination/vulkan/pvr_pipeline.c b/src/imagination/vulkan/pvr_pipeline.c index b5ea7448e22..482a56ebc6b 100644 --- a/src/imagination/vulkan/pvr_pipeline.c +++ b/src/imagination/vulkan/pvr_pipeline.c @@ -2297,6 +2297,7 @@ pvr_graphics_pipeline_init(struct pvr_device *device, &state, pCreateInfo, &rp_state, + 0, &all_state, NULL, 0, diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c index 1034fc44e78..0c6a9fbb822 100644 --- a/src/intel/vulkan/anv_pipeline.c +++ b/src/intel/vulkan/anv_pipeline.c @@ -3050,7 +3050,8 @@ anv_graphics_lib_pipeline_create(struct anv_device *device, result = vk_graphics_pipeline_state_fill(&device->vk, &pipeline->state, pCreateInfo, - NULL /* sp_info */, + NULL /* driver_rp */, + 0 /* driver_rp_flags */, &pipeline->all_state, NULL, 0, NULL); if (result != VK_SUCCESS) { anv_pipeline_finish(&pipeline->base.base, device); @@ -3166,7 +3167,8 @@ anv_graphics_pipeline_create(struct anv_device *device, } result = vk_graphics_pipeline_state_fill(&device->vk, &state, pCreateInfo, - NULL /* sp_info */, + NULL /* driver_rp */, + 0 /* driver_rp_flags */, &all, NULL, 0, NULL); if (result != VK_SUCCESS) { anv_pipeline_finish(&pipeline->base.base, device); diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c index ec674d84273..224990abb8e 100644 --- a/src/intel/vulkan/genX_pipeline.c +++ b/src/intel/vulkan/genX_pipeline.c @@ -1484,9 +1484,9 @@ emit_3dstate_gs(struct anv_graphics_pipeline *pipeline) } static bool -rp_has_ds_self_dep(const struct vk_render_pass_state *rp) +state_has_ds_self_dep(const struct vk_graphics_pipeline_state *state) { - return rp->pipeline_flags & + return state->pipeline_flags & VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; } @@ -1608,7 +1608,7 @@ emit_3dstate_ps(struct anv_graphics_pipeline *pipeline, static void emit_3dstate_ps_extra(struct anv_graphics_pipeline *pipeline, const struct vk_rasterization_state *rs, - const struct vk_render_pass_state *rp) + const struct vk_graphics_pipeline_state *state) { const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline); @@ -1633,7 +1633,7 @@ emit_3dstate_ps_extra(struct anv_graphics_pipeline *pipeline, * around to fetching from the input attachment and we may get the depth * or stencil value from the current draw rather than the previous one. */ - ps.PixelShaderKillsPixel = rp_has_ds_self_dep(rp) || + ps.PixelShaderKillsPixel = state_has_ds_self_dep(state) || wm_prog_data->uses_kill; ps.PixelShaderComputesStencil = wm_prog_data->computed_stencil; @@ -1678,7 +1678,7 @@ emit_3dstate_vf_statistics(struct anv_graphics_pipeline *pipeline) static void compute_kill_pixel(struct anv_graphics_pipeline *pipeline, const struct vk_multisample_state *ms, - const struct vk_render_pass_state *rp) + const struct vk_graphics_pipeline_state *state) { if (!anv_pipeline_has_stage(pipeline, MESA_SHADER_FRAGMENT)) { pipeline->kill_pixel = false; @@ -1702,7 +1702,7 @@ compute_kill_pixel(struct anv_graphics_pipeline *pipeline, * of an alpha test. */ pipeline->kill_pixel = - rp_has_ds_self_dep(rp) || + state_has_ds_self_dep(state) || wm_prog_data->uses_kill || wm_prog_data->uses_omask || (ms && ms->alpha_to_coverage_enable); @@ -1905,7 +1905,7 @@ genX(graphics_pipeline_emit)(struct anv_graphics_pipeline *pipeline, emit_rs_state(pipeline, state->ia, state->rs, state->ms, state->rp, urb_deref_block_size); emit_ms_state(pipeline, state->ms); - compute_kill_pixel(pipeline, state->ms, state->rp); + compute_kill_pixel(pipeline, state->ms, state); emit_3dstate_clip(pipeline, state->ia, state->vp, state->rs); @@ -2003,7 +2003,7 @@ genX(graphics_pipeline_emit)(struct anv_graphics_pipeline *pipeline, emit_3dstate_wm(pipeline, state->ia, state->rs, state->ms, state->cb, state->rp); emit_3dstate_ps(pipeline, state->ms, state->cb); - emit_3dstate_ps_extra(pipeline, state->rs, state->rp); + emit_3dstate_ps_extra(pipeline, state->rs, state); } #if GFX_VERx10 >= 125 diff --git a/src/intel/vulkan_hasvk/anv_pipeline.c b/src/intel/vulkan_hasvk/anv_pipeline.c index 6df9c3f79ff..79f243fb925 100644 --- a/src/intel/vulkan_hasvk/anv_pipeline.c +++ b/src/intel/vulkan_hasvk/anv_pipeline.c @@ -1867,7 +1867,8 @@ anv_graphics_pipeline_create(struct anv_device *device, struct vk_graphics_pipeline_all_state all; struct vk_graphics_pipeline_state state = { }; result = vk_graphics_pipeline_state_fill(&device->vk, &state, pCreateInfo, - NULL /* sp_info */, + NULL /* driver_rp */, + 0 /* driver_rp_flags */, &all, NULL, 0, NULL); if (result != VK_SUCCESS) { vk_free2(&device->vk.alloc, pAllocator, pipeline); diff --git a/src/intel/vulkan_hasvk/genX_pipeline.c b/src/intel/vulkan_hasvk/genX_pipeline.c index 5681c8a9a78..c6dd12748aa 100644 --- a/src/intel/vulkan_hasvk/genX_pipeline.c +++ b/src/intel/vulkan_hasvk/genX_pipeline.c @@ -1541,9 +1541,9 @@ emit_3dstate_gs(struct anv_graphics_pipeline *pipeline, } static bool -rp_has_ds_self_dep(const struct vk_render_pass_state *rp) +state_has_ds_self_dep(const struct vk_graphics_pipeline_state *state) { - return rp->pipeline_flags & + return state->pipeline_flags & VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; } @@ -1553,7 +1553,7 @@ emit_3dstate_wm(struct anv_graphics_pipeline *pipeline, const struct vk_rasterization_state *rs, const struct vk_multisample_state *ms, const struct vk_color_blend_state *cb, - const struct vk_render_pass_state *rp) + const struct vk_graphics_pipeline_state *state) { const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline); @@ -1612,7 +1612,7 @@ emit_3dstate_wm(struct anv_graphics_pipeline *pipeline, * may get the depth or stencil value from the current draw rather * than the previous one. */ - wm.PixelShaderKillsPixel = rp_has_ds_self_dep(rp) || + wm.PixelShaderKillsPixel = state_has_ds_self_dep(state) || wm_prog_data->uses_kill || wm_prog_data->uses_omask; @@ -1744,7 +1744,7 @@ emit_3dstate_ps(struct anv_graphics_pipeline *pipeline, static void emit_3dstate_ps_extra(struct anv_graphics_pipeline *pipeline, const struct vk_rasterization_state *rs, - const struct vk_render_pass_state *rp) + const struct vk_graphics_pipeline_state *state) { const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline); @@ -1769,7 +1769,7 @@ emit_3dstate_ps_extra(struct anv_graphics_pipeline *pipeline, * around to fetching from the input attachment and we may get the depth * or stencil value from the current draw rather than the previous one. */ - ps.PixelShaderKillsPixel = rp_has_ds_self_dep(rp) || + ps.PixelShaderKillsPixel = state_has_ds_self_dep(state) || wm_prog_data->uses_kill; ps.PixelShaderUsesInputCoverageMask = wm_prog_data->uses_sample_mask; @@ -1788,7 +1788,7 @@ emit_3dstate_vf_statistics(struct anv_graphics_pipeline *pipeline) static void compute_kill_pixel(struct anv_graphics_pipeline *pipeline, const struct vk_multisample_state *ms, - const struct vk_render_pass_state *rp) + const struct vk_graphics_pipeline_state *state) { if (!anv_pipeline_has_stage(pipeline, MESA_SHADER_FRAGMENT)) { pipeline->kill_pixel = false; @@ -1812,7 +1812,7 @@ compute_kill_pixel(struct anv_graphics_pipeline *pipeline, * of an alpha test. */ pipeline->kill_pixel = - rp_has_ds_self_dep(rp) || + state_has_ds_self_dep(state) || wm_prog_data->uses_kill || wm_prog_data->uses_omask || (ms && ms->alpha_to_coverage_enable); @@ -1830,7 +1830,7 @@ genX(graphics_pipeline_emit)(struct anv_graphics_pipeline *pipeline, urb_deref_block_size); emit_ms_state(pipeline, state->ms); emit_cb_state(pipeline, state->cb, state->ms); - compute_kill_pixel(pipeline, state->ms, state->rp); + compute_kill_pixel(pipeline, state->ms, state); emit_3dstate_clip(pipeline, state->ia, state->vp, state->rs); @@ -1865,10 +1865,10 @@ genX(graphics_pipeline_emit)(struct anv_graphics_pipeline *pipeline, emit_3dstate_sbe(pipeline); emit_3dstate_wm(pipeline, state->ia, state->rs, - state->ms, state->cb, state->rp); + state->ms, state->cb, state); emit_3dstate_ps(pipeline, state->ms, state->cb); #if GFX_VER >= 8 - emit_3dstate_ps_extra(pipeline, state->rs, state->rp); + emit_3dstate_ps_extra(pipeline, state->rs, state); #endif } diff --git a/src/nouveau/vulkan/nvk_graphics_pipeline.c b/src/nouveau/vulkan/nvk_graphics_pipeline.c index fd6a966c6ba..49d11c09216 100644 --- a/src/nouveau/vulkan/nvk_graphics_pipeline.c +++ b/src/nouveau/vulkan/nvk_graphics_pipeline.c @@ -44,11 +44,11 @@ emit_pipeline_rs_state(struct nv_push *p, static void nvk_populate_fs_key(struct nvk_fs_key *key, const struct vk_multisample_state *ms, - const struct vk_render_pass_state *rp) + const struct vk_graphics_pipeline_state *state) { memset(key, 0, sizeof(*key)); - if (rp->pipeline_flags & + if (state->pipeline_flags & VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT) key->zs_self_dep = true; @@ -321,7 +321,7 @@ nvk_graphics_pipeline_create(struct nvk_device *dev, struct vk_graphics_pipeline_all_state all; struct vk_graphics_pipeline_state state = {}; result = vk_graphics_pipeline_state_fill(&dev->vk, &state, pCreateInfo, - NULL, &all, NULL, 0, NULL); + NULL, 0, &all, NULL, 0, NULL); assert(result == VK_SUCCESS); nir_shader *nir[MESA_SHADER_STAGES] = {}; @@ -358,7 +358,7 @@ nvk_graphics_pipeline_create(struct nvk_device *dev, struct nvk_fs_key fs_key_tmp, *fs_key = NULL; if (stage == MESA_SHADER_FRAGMENT) { - nvk_populate_fs_key(&fs_key_tmp, state.ms, state.rp); + nvk_populate_fs_key(&fs_key_tmp, state.ms, &state); fs_key = &fs_key_tmp; } diff --git a/src/vulkan/runtime/vk_graphics_state.c b/src/vulkan/runtime/vk_graphics_state.c index aa1c62176e7..9888bd92bf4 100644 --- a/src/vulkan/runtime/vk_graphics_state.c +++ b/src/vulkan/runtime/vk_graphics_state.c @@ -5,6 +5,7 @@ #include "vk_common_entrypoints.h" #include "vk_device.h" #include "vk_log.h" +#include "vk_pipeline.h" #include "vk_render_pass.h" #include "vk_standard_sample_locations.h" #include "vk_util.h" @@ -1032,11 +1033,11 @@ vk_render_pass_state_is_complete(const struct vk_render_pass_state *rp) } static void -vk_render_pass_state_init(struct vk_render_pass_state *rp, - const struct vk_render_pass_state *old_rp, - const struct vk_render_pass_state *driver_rp, - const VkGraphicsPipelineCreateInfo *info, - VkGraphicsPipelineLibraryFlagsEXT lib) +vk_pipeline_flags_init(struct vk_graphics_pipeline_state *state, + VkPipelineCreateFlags2KHR driver_rp_flags, + bool has_driver_rp, + const VkGraphicsPipelineCreateInfo *info, + VkGraphicsPipelineLibraryFlagsEXT lib) { VkPipelineCreateFlags2KHR valid_pipeline_flags = 0; if (lib & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) { @@ -1049,22 +1050,43 @@ vk_render_pass_state_init(struct vk_render_pass_state *rp, VK_PIPELINE_CREATE_2_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT | VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; } - const VkPipelineCreateFlags2KHR pipeline_flags = - (driver_rp ? driver_rp->pipeline_flags : + const VkPipelineCreateFlags2KHR renderpass_flags = + (has_driver_rp ? driver_rp_flags : vk_get_pipeline_rendering_flags(info)) & valid_pipeline_flags; + const VkPipelineCreateFlags2KHR pipeline_flags = + vk_graphics_pipeline_create_flags(info) & valid_pipeline_flags; + + bool pipeline_feedback_loop = pipeline_flags & + (VK_PIPELINE_CREATE_2_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT | + VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT); + + bool renderpass_feedback_loop = renderpass_flags & + (VK_PIPELINE_CREATE_2_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT | + VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT); + + state->pipeline_flags |= renderpass_flags | pipeline_flags; + state->feedback_loop_not_input_only |= + pipeline_feedback_loop || (!has_driver_rp && renderpass_feedback_loop); +} + +static void +vk_render_pass_state_init(struct vk_render_pass_state *rp, + const struct vk_render_pass_state *old_rp, + const struct vk_render_pass_state *driver_rp, + const VkGraphicsPipelineCreateInfo *info, + VkGraphicsPipelineLibraryFlagsEXT lib) +{ /* If we already have render pass state and it has attachment info, then * it's complete and we don't need a new one. The one caveat here is that * we may need to add in some rendering flags. */ if (old_rp != NULL && vk_render_pass_state_is_complete(old_rp)) { *rp = *old_rp; - rp->pipeline_flags |= pipeline_flags; return; } *rp = (struct vk_render_pass_state) { - .pipeline_flags = pipeline_flags, .depth_attachment_format = VK_FORMAT_UNDEFINED, .stencil_attachment_format = VK_FORMAT_UNDEFINED, }; @@ -1228,6 +1250,7 @@ vk_graphics_pipeline_state_fill(const struct vk_device *device, struct vk_graphics_pipeline_state *state, const VkGraphicsPipelineCreateInfo *info, const struct vk_render_pass_state *driver_rp, + VkPipelineCreateFlags2KHR driver_rp_flags, struct vk_graphics_pipeline_all_state *all, const VkAllocationCallbacks *alloc, VkSystemAllocationScope scope, @@ -1360,6 +1383,11 @@ vk_graphics_pipeline_state_fill(const struct vk_device *device, state->rp = NULL; } + 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); + } + if (lib & VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT) { /* From the Vulkan 1.3.218 spec: * @@ -1599,6 +1627,9 @@ vk_graphics_pipeline_state_merge(struct vk_graphics_pipeline_state *dst, dst->shader_stages |= src->shader_stages; + dst->pipeline_flags |= src->pipeline_flags; + dst->feedback_loop_not_input_only |= src->feedback_loop_not_input_only; + /* Render pass state needs special care because a render pass state may be * incomplete (view mask only). See vk_render_pass_state_init(). */ @@ -1690,6 +1721,10 @@ vk_graphics_pipeline_state_copy(const struct vk_device *device, #undef COPY_STATE_IF_NEEDED + state->pipeline_flags = old_state->pipeline_flags; + state->feedback_loop_not_input_only = + old_state->feedback_loop_not_input_only; + vk_graphics_pipeline_state_validate(state); return VK_SUCCESS; } diff --git a/src/vulkan/runtime/vk_graphics_state.h b/src/vulkan/runtime/vk_graphics_state.h index 4efee035827..392ef9f5277 100644 --- a/src/vulkan/runtime/vk_graphics_state.h +++ b/src/vulkan/runtime/vk_graphics_state.h @@ -675,16 +675,6 @@ struct vk_render_pass_state { /** VkPipelineRenderingCreateInfo::viewMask */ uint32_t view_mask; - /** Render pass flags from VkGraphicsPipelineCreateInfo::flags - * - * For drivers which use vk_render_pass, this will also include flags - * generated based on subpass self-dependencies and fragment density map. - */ - VkPipelineCreateFlags2KHR pipeline_flags; - - /* True if any feedback loops only involve input attachments. */ - bool feedback_loop_input_only; - /** VkPipelineRenderingCreateInfo::colorAttachmentCount */ uint8_t color_attachment_count; @@ -858,6 +848,23 @@ struct vk_graphics_pipeline_state { VkShaderStageFlags shader_stages; + /** Flags from VkGraphicsPipelineCreateInfo::flags that are considered part + * of a stage and need to be merged when linking libraries. + * + * For drivers which use vk_render_pass, this will also include flags + * generated based on subpass self-dependencies and fragment density map. + */ + VkPipelineCreateFlags2KHR pipeline_flags; + + /* True if there are feedback loops that do not involve input attachments + * managed by the driver. This is set to true by the runtime if there + * are loops indicated by a pipeline flag (which may involve any image + * rather than only input attachments under the control of the driver) or + * there was no driver-provided render pass info struct (because input + * attachments for emulated renderpasses cannot be managed by the driver). + */ + bool feedback_loop_not_input_only; + /** Vertex input state */ const struct vk_vertex_input_state *vi; @@ -922,6 +929,10 @@ struct vk_graphics_pipeline_state { * passes itself. This should be NULL for drivers * that use the common render pass infrastructure * built on top of dynamic rendering. + * :param driver_rp_flags: |in| Pipeline create flags implied by the + * renderpass or subpass if the driver implements + * render passes itself. This is only used if + * driver_rp is non-NULL. * :param all: |in| The vk_graphics_pipeline_all_state to use to * back any newly needed states. If NULL, newly * needed states will be dynamically allocated @@ -938,7 +949,8 @@ VkResult vk_graphics_pipeline_state_fill(const struct vk_device *device, struct vk_graphics_pipeline_state *state, const VkGraphicsPipelineCreateInfo *info, - const struct vk_render_pass_state *rp_info, + const struct vk_render_pass_state *driver_rp, + VkPipelineCreateFlags2KHR driver_rp_flags, struct vk_graphics_pipeline_all_state *all, const VkAllocationCallbacks *alloc, VkSystemAllocationScope scope, diff --git a/src/vulkan/runtime/vk_render_pass.c b/src/vulkan/runtime/vk_render_pass.c index 16106153c03..826fd21a9f3 100644 --- a/src/vulkan/runtime/vk_render_pass.c +++ b/src/vulkan/runtime/vk_render_pass.c @@ -30,7 +30,6 @@ #include "vk_format.h" #include "vk_framebuffer.h" #include "vk_image.h" -#include "vk_pipeline.h" #include "vk_util.h" #include "util/log.h" @@ -842,12 +841,7 @@ vk_get_pipeline_rendering_create_info(const VkGraphicsPipelineCreateInfo *info) VkPipelineCreateFlags2KHR vk_get_pipeline_rendering_flags(const VkGraphicsPipelineCreateInfo *info) { - VkPipelineCreateFlags2KHR rendering_flags = - vk_graphics_pipeline_create_flags(info) & - (VK_PIPELINE_CREATE_2_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT | - VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT | - VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR | - VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT); + VkPipelineCreateFlags2KHR rendering_flags = 0; VK_FROM_HANDLE(vk_render_pass, render_pass, info->renderPass); if (render_pass != NULL) {