Handle mixed samples attachments (V2) (#3667)

* video_core: Refactor render target bind to allow disabling MSAA

* video_core: Implement swapping of backing samples

* clang format

* video_core: Better implementation

Instead of downgrading to 1 sample, always try to match depth samples. This avoids needing to copy depth-stencil attachment and copying multisampled stencil is not possible on some vendors

* video_core: Small bugfixes

* image: Add null check

* vk_rasterizer: Swap backing samples on resolve dst

* vk_presenter: Reset backing samples before present

* video_core: Small refactor to make this implementation better

* reinterpret: Fix channel check for degamma

Seems this was simpler than I thought, hardware doesn't apply degamma on the W channel regardless of swizzle

* image: Add missing end rendering call

* blit_helper: Fix bug in old reinterpret path

* blit_helper: Remove unused layer vertex

Should be used in the future if copying many layers is needed

* vk_rasterizer: Apply suggestion

* vk_rasterizer: More bind refactor

* vk_instance: Re-enable extensions
This commit is contained in:
TheTurtle
2025-09-29 16:27:39 +03:00
committed by GitHub
parent cad027845f
commit a35c9f3586
32 changed files with 1166 additions and 847 deletions

View File

@@ -233,13 +233,8 @@ bool VideoOutDriver::SubmitFlip(VideoOutPort* port, s32 index, s64 flip_arg,
}
if (!is_eop) {
// Before processing the flip we need to ask GPU thread to flush command list as at this
// point VO surface is ready to be presented, and we will need have an actual state of
// Vulkan image at the time of frame presentation.
liverpool->SendCommand([=, this]() {
presenter->FlushDraw();
SubmitFlipInternal(port, index, flip_arg, is_eop);
});
// Non EOP flips can arrive from any thread so ask GPU thread to perform them
liverpool->SendCommand([=, this]() { SubmitFlipInternal(port, index, flip_arg, is_eop); });
} else {
SubmitFlipInternal(port, index, flip_arg, is_eop);
}
@@ -247,15 +242,14 @@ bool VideoOutDriver::SubmitFlip(VideoOutPort* port, s32 index, s64 flip_arg,
return true;
}
void VideoOutDriver::SubmitFlipInternal(VideoOutPort* port, s32 index, s64 flip_arg,
bool is_eop /*= false*/) {
void VideoOutDriver::SubmitFlipInternal(VideoOutPort* port, s32 index, s64 flip_arg, bool is_eop) {
Vulkan::Frame* frame;
if (index == -1) {
frame = presenter->PrepareBlankFrame(is_eop);
frame = presenter->PrepareBlankFrame(false);
} else {
const auto& buffer = port->buffer_slots[index];
const auto& group = port->groups[buffer.group_index];
frame = presenter->PrepareFrame(group, buffer.address_left, is_eop);
frame = presenter->PrepareFrame(group, buffer.address_left);
}
std::scoped_lock lock{mutex};