mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 00:12:40 +00:00
Track depth and stencil attachment feedback across graphics stages
Co-authored-by: TarkusR <90155059+TarkusR@users.noreply.github.com>
This commit is contained in:
1 parent
51c34d1a24
commit
66cc2fe26d
5 files changed
+293
-66
No files matched your search
@@ -453,8 +453,10 @@ struct DrawCallInfo {
|
||||
|
||||
RenderState RenderExecutor::AcquireRenderTargets(CommandBuffer& buffer, RenderColorInfo* colors,
|
||||
uint32_t color_count, RenderDepthInfo& depth,
|
||||
const std::optional<PreparedBindings>& pixel) {
|
||||
vk::ImageAspectFlags& feedback_aspects,
|
||||
std::span<PreparedBindings* const> stages) {
|
||||
EXIT_IF(colors == nullptr || color_count > RENDER_COLOR_ATTACHMENTS_MAX);
|
||||
feedback_aspects = {};
|
||||
auto& cache = m_context.GetTextureCache();
|
||||
RenderState state {};
|
||||
state.width = std::numeric_limits<uint32_t>::max();
|
||||
@@ -529,28 +531,29 @@ RenderState RenderExecutor::AcquireRenderTargets(CommandBuffer& buffer, RenderCo
|
||||
image.info.data.address, depth.desc.view_info.base_layer,
|
||||
depth.desc.view_info.layer_count);
|
||||
EXIT_IF(image_view == nullptr || image.backing.samples != depth.desc.info.samples);
|
||||
const bool feedback = depth.depth_write_enable && pixel &&
|
||||
std::ranges::any_of(pixel->images, [&](const TextureBinding& binding) {
|
||||
if (binding.image_id != depth.image_id ||
|
||||
binding.desc.type != TextureCache::BindingType::Texture) {
|
||||
return false;
|
||||
}
|
||||
const auto native =
|
||||
std::ranges::find(image.views, binding.image_view, &CachedImageView::view);
|
||||
EXIT_IF(native == image.views.end());
|
||||
const auto& sampled = native->info;
|
||||
const auto& target = depth.desc.view_info;
|
||||
return (sampled.aspect & vk::ImageAspectFlagBits::eDepth) &&
|
||||
ImageRangeOverlaps(sampled.base_level, sampled.level_count,
|
||||
target.base_level, target.level_count) &&
|
||||
ImageRangeOverlaps(sampled.base_layer, sampled.layer_count,
|
||||
target.base_layer, target.layer_count);
|
||||
});
|
||||
if (feedback && !m_context.GetGraphics().attachment_feedback_loop_enabled) {
|
||||
const auto draw_writes = depth.AttachmentWriteAspects();
|
||||
vk::ImageAspectFlags sampled_aspects;
|
||||
for (const auto* stage: stages) {
|
||||
for (const auto& binding: stage->images) {
|
||||
if (binding.image_id != depth.image_id ||
|
||||
binding.desc.type != TextureCache::BindingType::Texture) continue;
|
||||
const auto native =
|
||||
std::ranges::find(image.views, binding.image_view, &CachedImageView::view);
|
||||
EXIT_IF(native == image.views.end());
|
||||
sampled_aspects |= native->info.aspect;
|
||||
feedback_aspects |= DepthFeedbackAspects(draw_writes, depth.desc.view_info,
|
||||
native->info);
|
||||
}
|
||||
}
|
||||
if (feedback_aspects && !m_context.GetGraphics().attachment_feedback_loop_enabled) {
|
||||
EXIT("depth attachment feedback loop is not supported by the host\n");
|
||||
}
|
||||
const auto layout = feedback ? vk::ImageLayout::eAttachmentFeedbackLoopOptimalEXT
|
||||
: depth_attachment_layout(depth);
|
||||
auto layout = depth_attachment_layout(depth);
|
||||
if (sampled_aspects & ~DepthReadableAspects(layout)) {
|
||||
layout = m_context.GetGraphics().attachment_feedback_loop_enabled
|
||||
? vk::ImageLayout::eAttachmentFeedbackLoopOptimalEXT
|
||||
: vk::ImageLayout::eGeneral;
|
||||
}
|
||||
// The attachment store writes even when guest depth/stencil tests do not.
|
||||
const auto access = vk::AccessFlagBits2::eDepthStencilAttachmentRead |
|
||||
vk::AccessFlagBits2::eDepthStencilAttachmentWrite;
|
||||
@@ -1100,9 +1103,10 @@ void RenderExecutor::ExecutePreparedDraw(uint64_t submit_id, CommandBuffer& buff
|
||||
std::span {state.color_info, state.color_count}, state.depth_info, vertex_stages, buffer,
|
||||
state.ps_active ? &state.ps_input_info : nullptr, topology, primitive_restart_enable,
|
||||
state.programs);
|
||||
vk::ImageAspectFlags feedback_aspects;
|
||||
const auto rendering =
|
||||
AcquireRenderTargets(buffer, state.color_info, state.color_count, state.depth_info,
|
||||
bindings.pixel);
|
||||
feedback_aspects, stages);
|
||||
|
||||
// Resource preparation above may synchronously finish and restart the scheduler. From this
|
||||
// point onward, every operation targets the current command buffer and cannot touch guest
|
||||
@@ -1134,11 +1138,7 @@ void RenderExecutor::ExecutePreparedDraw(uint64_t submit_id, CommandBuffer& buff
|
||||
|
||||
SetGraphicsDynamicParams(buffer, vk_buffer, vertex_stages.back(), state.depth_info, rendering);
|
||||
if (m_context.GetGraphics().attachment_feedback_loop_enabled) {
|
||||
vk_buffer.setAttachmentFeedbackLoopEnableEXT(
|
||||
rendering.depth_stencil_attachment.image_layout ==
|
||||
vk::ImageLayout::eAttachmentFeedbackLoopOptimalEXT
|
||||
? vk::ImageAspectFlags {vk::ImageAspectFlagBits::eDepth}
|
||||
: vk::ImageAspectFlags {});
|
||||
vk_buffer.setAttachmentFeedbackLoopEnableEXT(feedback_aspects);
|
||||
}
|
||||
|
||||
LogDrawPhase(draw.Name(), "BeginRendering");
|
||||
|
||||
Reference in new issue
Block a user