diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 45e7c8ad810..f04542e3406 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -1778,20 +1778,24 @@ unbind_samplerview(struct zink_context *ctx, gl_shader_stage stage, unsigned slo struct zink_resource *res = zink_resource(sv->base.texture); res->sampler_bind_count[stage == MESA_SHADER_COMPUTE]--; if (stage != MESA_SHADER_COMPUTE && !res->sampler_bind_count[0] && res->fb_bind_count) { - unsigned feedback_loops = ctx->feedback_loops; u_foreach_bit(idx, res->fb_binds) { if (ctx->feedback_loops & BITFIELD_BIT(idx)) { ctx->dynamic_fb.attachments[idx].imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; ctx->rp_layout_changed = true; } + unsigned feedback_loops = ctx->feedback_loops; ctx->feedback_loops &= ~BITFIELD_BIT(idx); - } - if (!zink_screen(ctx->base.screen)->driver_workarounds.always_feedback_loop && - feedback_loops && !ctx->feedback_loops) { - /* unset feedback loop bits */ - if (ctx->gfx_pipeline_state.feedback_loop) - ctx->gfx_pipeline_state.dirty = true; - ctx->gfx_pipeline_state.feedback_loop = false; + if (feedback_loops != ctx->feedback_loops) { + if (idx == PIPE_MAX_COLOR_BUFS && !zink_screen(ctx->base.screen)->driver_workarounds.always_feedback_loop_zs) { + if (ctx->gfx_pipeline_state.feedback_loop_zs) + ctx->gfx_pipeline_state.dirty = true; + ctx->gfx_pipeline_state.feedback_loop_zs = false; + } else if (idx < PIPE_MAX_COLOR_BUFS && !zink_screen(ctx->base.screen)->driver_workarounds.always_feedback_loop) { + if (ctx->gfx_pipeline_state.feedback_loop) + ctx->gfx_pipeline_state.dirty = true; + ctx->gfx_pipeline_state.feedback_loop = false; + } + } } } update_res_bind_count(ctx, res, stage == MESA_SHADER_COMPUTE, true); @@ -2829,12 +2833,16 @@ unbind_fb_surface(struct zink_context *ctx, struct pipe_surface *surf, unsigned ctx->rp_layout_changed = true; } ctx->feedback_loops &= ~BITFIELD_BIT(idx); - if (!zink_screen(ctx->base.screen)->driver_workarounds.always_feedback_loop && - feedback_loops && !ctx->feedback_loops) { - /* unset feedback loop bits */ - if (ctx->gfx_pipeline_state.feedback_loop) - ctx->gfx_pipeline_state.dirty = true; - ctx->gfx_pipeline_state.feedback_loop = false; + if (feedback_loops != ctx->feedback_loops) { + if (idx == PIPE_MAX_COLOR_BUFS && !zink_screen(ctx->base.screen)->driver_workarounds.always_feedback_loop_zs) { + if (ctx->gfx_pipeline_state.feedback_loop_zs) + ctx->gfx_pipeline_state.dirty = true; + ctx->gfx_pipeline_state.feedback_loop_zs = false; + } else if (idx < PIPE_MAX_COLOR_BUFS && !zink_screen(ctx->base.screen)->driver_workarounds.always_feedback_loop) { + if (ctx->gfx_pipeline_state.feedback_loop) + ctx->gfx_pipeline_state.dirty = true; + ctx->gfx_pipeline_state.feedback_loop = false; + } } res->fb_binds &= ~BITFIELD_BIT(idx); if (!res->fb_bind_count) { diff --git a/src/gallium/drivers/zink/zink_descriptors.c b/src/gallium/drivers/zink/zink_descriptors.c index 92ab3e091e4..a5520603a67 100644 --- a/src/gallium/drivers/zink/zink_descriptors.c +++ b/src/gallium/drivers/zink/zink_descriptors.c @@ -267,11 +267,6 @@ zink_descriptor_util_image_layout_eval(const struct zink_context *ctx, const str } if (res->image_bind_count[is_compute]) return VK_IMAGE_LAYOUT_GENERAL; - if (res->aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { - if (!is_compute && res->fb_bind_count && - ctx->gfx_pipeline_state.render_pass && ctx->gfx_pipeline_state.render_pass->state.rts[ctx->fb_state.nr_cbufs].mixed_zs) - return VK_IMAGE_LAYOUT_GENERAL; - } if (!is_compute && res->fb_bind_count && res->sampler_bind_count[0]) { /* feedback loop */ if (zink_screen(ctx->base.screen)->info.have_EXT_attachment_feedback_loop_layout) diff --git a/src/gallium/drivers/zink/zink_draw.cpp b/src/gallium/drivers/zink/zink_draw.cpp index b179c55a996..c833f35f4c1 100644 --- a/src/gallium/drivers/zink/zink_draw.cpp +++ b/src/gallium/drivers/zink/zink_draw.cpp @@ -298,13 +298,23 @@ update_barriers(struct zink_context *ctx, bool is_compute, if (!is_compute) { if (res->fb_bind_count && res->sampler_bind_count[0] && (!(ctx->feedback_loops & res->fb_binds))) { /* new feedback loop detected */ - if (!ctx->gfx_pipeline_state.feedback_loop) - ctx->gfx_pipeline_state.dirty = true; - ctx->gfx_pipeline_state.feedback_loop = true; + if (res->aspect == VK_IMAGE_ASPECT_COLOR_BIT) { + if (!ctx->gfx_pipeline_state.feedback_loop) + ctx->gfx_pipeline_state.dirty = true; + ctx->gfx_pipeline_state.feedback_loop = true; + } else { + if (!ctx->gfx_pipeline_state.feedback_loop_zs) + ctx->gfx_pipeline_state.dirty = true; + ctx->gfx_pipeline_state.feedback_loop_zs = true; + } ctx->rp_layout_changed = true; ctx->feedback_loops |= res->fb_binds; - u_foreach_bit(idx, res->fb_binds) - ctx->dynamic_fb.attachments[idx].imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT; + u_foreach_bit(idx, res->fb_binds) { + if (zink_screen(ctx->base.screen)->info.have_EXT_attachment_feedback_loop_layout) + ctx->dynamic_fb.attachments[idx].imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT; + else + ctx->dynamic_fb.attachments[idx].imageLayout = VK_IMAGE_LAYOUT_GENERAL; + } } } if (layout != res->layout) diff --git a/src/gallium/drivers/zink/zink_pipeline.c b/src/gallium/drivers/zink/zink_pipeline.c index 913b4821a3c..e6f5abcd135 100644 --- a/src/gallium/drivers/zink/zink_pipeline.c +++ b/src/gallium/drivers/zink/zink_pipeline.c @@ -323,13 +323,18 @@ zink_create_gfx_pipeline(struct zink_screen *screen, VkGraphicsPipelineCreateInfo pci = {0}; pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + static bool feedback_warn = false; if (state->feedback_loop) { if (screen->info.have_EXT_attachment_feedback_loop_layout) - pci.flags = VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; - else { - static bool warn = false; - warn_missing_feature(warn, "EXT_attachment_feedback_loop_layout"); - } + pci.flags |= VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; + else + warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout"); + } + if (state->feedback_loop_zs) { + if (screen->info.have_EXT_attachment_feedback_loop_layout) + pci.flags |= VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; + else + warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout"); } pci.layout = prog->base.layout; if (state->render_pass) @@ -494,13 +499,18 @@ zink_create_gfx_pipeline_output(struct zink_screen *screen, struct zink_gfx_pipe pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; pci.pNext = &gplci; pci.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; + static bool feedback_warn = false; if (state->feedback_loop) { if (screen->info.have_EXT_attachment_feedback_loop_layout) - pci.flags = VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; - else { - static bool warn = false; - warn_missing_feature(warn, "EXT_attachment_feedback_loop_layout"); - } + pci.flags |= VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; + else + warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout"); + } + if (state->feedback_loop_zs) { + if (screen->info.have_EXT_attachment_feedback_loop_layout) + pci.flags |= VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; + else + warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout"); } pci.pColorBlendState = &blend_state; pci.pMultisampleState = &ms_state; diff --git a/src/gallium/drivers/zink/zink_render_pass.c b/src/gallium/drivers/zink/zink_render_pass.c index 295ccba1ea6..eb4b61f18e1 100644 --- a/src/gallium/drivers/zink/zink_render_pass.c +++ b/src/gallium/drivers/zink/zink_render_pass.c @@ -58,8 +58,6 @@ get_zs_rt_layout(const struct zink_rt_attrib *rt) bool has_clear = rt->clear_color || rt->clear_stencil; if (rt->feedback_loop) return VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT; - if (rt->mixed_zs) - return VK_IMAGE_LAYOUT_GENERAL; return rt->needs_write || has_clear ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; } @@ -279,14 +277,10 @@ zink_render_pass_attachment_get_barrier_info(const struct zink_rt_attrib *rt, bo } *pipeline = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; - if (rt->mixed_zs) { - *access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - } else { - if (!rt->clear_color && !rt->clear_stencil) - *access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; - if (rt->clear_color || rt->clear_stencil || rt->needs_write) - *access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - } + if (!rt->clear_color && !rt->clear_stencil) + *access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; + if (rt->clear_color || rt->clear_stencil || rt->needs_write) + *access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; return get_zs_rt_layout(rt); } @@ -351,12 +345,6 @@ zink_init_zs_attachment(struct zink_context *ctx, struct zink_rt_attrib *rt) bool needs_write_s = rt->clear_stencil || (outputs_written & BITFIELD64_BIT(FRAG_RESULT_STENCIL)) || (zink_fb_clear_enabled(ctx, PIPE_MAX_COLOR_BUFS) && (zink_fb_clear_element(fb_clear, 0)->zs.bits & PIPE_CLEAR_STENCIL)); - if (!needs_write_z && (!ctx->dsa_state || !ctx->dsa_state->base.depth_enabled)) - /* depth sample, stencil write */ - rt->mixed_zs = needs_write_s && zsbuf->bind_count[0]; - else - /* depth write + sample */ - rt->mixed_zs = needs_write_z && zsbuf->bind_count[0]; rt->needs_write = needs_write_z | needs_write_s; rt->invalid = !zsbuf->valid; rt->feedback_loop = (ctx->feedback_loops & BITFIELD_BIT(PIPE_MAX_COLOR_BUFS)) > 0; diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index aa4cbee6fa9..74cb0e2fdcc 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -2281,6 +2281,18 @@ init_driver_workarounds(struct zink_screen *screen) default: break; } + /* these drivers don't use VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT, so it can always be set */ + switch (screen->info.driver_props.driverID) { + case VK_DRIVER_ID_MESA_RADV: + case VK_DRIVER_ID_MESA_LLVMPIPE: + case VK_DRIVER_ID_MESA_VENUS: + case VK_DRIVER_ID_NVIDIA_PROPRIETARY: + case VK_DRIVER_ID_IMAGINATION_PROPRIETARY: + screen->driver_workarounds.always_feedback_loop_zs = screen->info.have_EXT_attachment_feedback_loop_layout; + break; + default: + break; + } } static struct zink_screen * diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index bc4561eded4..788e5d72886 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -647,8 +647,9 @@ struct zink_gfx_pipeline_state { uint32_t force_persample_interp:1; //duplicated for gpl hashing /* order matches zink_gfx_output_key: uint16_t offset */ uint32_t rast_samples:8; // 2 extra bits (can be used for new members) - uint32_t min_samples:7; // 1 extra bit (can be used for new members) + uint32_t min_samples:6; uint32_t feedback_loop : 1; + uint32_t feedback_loop_zs : 1; VkSampleMask sample_mask; unsigned rp_state; uint32_t blend_id; @@ -801,8 +802,9 @@ struct zink_gfx_output_key { uint32_t _pad:15; uint32_t force_persample_interp:1; uint32_t rast_samples:8; // 2 extra bits (can be used for new members) - uint32_t min_samples:7; // 1 extra bit (can be used for new members) + uint32_t min_samples:6; uint32_t feedback_loop : 1; + uint32_t feedback_loop_zs : 1; VkSampleMask sample_mask; unsigned rp_state; @@ -872,7 +874,6 @@ struct zink_rt_attrib { bool invalid; bool needs_write; bool resolve; - bool mixed_zs; bool feedback_loop; }; @@ -1169,6 +1170,7 @@ struct zink_screen { bool depth_clip_control_missing; bool implicit_sync; bool always_feedback_loop; + bool always_feedback_loop_zs; unsigned z16_unscaled_bias; unsigned z24_unscaled_bias; } driver_workarounds;