open [12461] Rework Nvdec and VIC to fix out-of-order videos, and speed up decoding. #12461

Open
Accord wants to merge 2 commits from __refs_pull_12461_head into master
Owner

Branch: __refs_pull_12461_head

Labels: gpu, do-not-merge, early-access-merge, android-merge

Kelebek1 opened issue at 2023-12-24 16:54:

This is a rework of Nvdec and VIC, primarily VIC, aiming to fix some videos which play out of order, like My Girlfriend Is A Mermaid, and also to speed up decoding where possible.
Nvdec and VIC operate together, nvdec takes in some frame inputs, decodes the frame, and writes the resulting luma/chroma to memory at addresses given the registers. VIC then reads these surfaces, blends them together and performing other compositing features (scaling/rotation/colour conversion/etc), and then writes the composited image back to memory.
Currently, to avoid some extra effort, we just store the resulting frames from nvdec in a queue, and then pop a frame each time VIC is called. This works for the majority of games, but some want the VIC to grab frames out of order relative to nvdec. For example, from My Girlfriend Is A Mermaid:

Nvdec storing to 0x73D000
Nvdec storing to 0xA3D000
Nvdec storing to 0xD3D000
Nvdec storing to 0x103D000
Nvdec storing to 0x133D000
Nvdec storing to 0x163D000
Nvdec storing to 0x193D000
Nvdec storing to 0x1C3D000
VIC reading from 0x73D000
VIC reading from 0xD3D000
VIC reading from 0x103D000
VIC reading from 0xA3D000
VIC reading from 0x163D000
VIC reading from 0x193D000
Nvdec storing to 0x103D000

You can see VIC expects to read 0xD3D000 as its second frame to output, but nvdec's second frame was 0xA3D000, and this isn't actually requested by VIC until frame 4. This sort of re-ordering doesn't work using a queue, so instead I've switched this over to a map keyed on the offset, so VIC can find the right frame and correct the frame order.
Unfortunately it's not that simple, as we use ffmpeg to decode the frames, we can't make ffmpeg return frames in decode order to fit the offsets, which this strategy requires. That means when we call receive frame on ffmpeg, it can return us a different frame than we expect, and we associate the wrong frames with the wrong offsets, and again read them out of the expected order. As a hacky workaround for this, we implement the same suggestion @jduncanator suggested for Ryujinx: https://github.com/Ryujinx/Ryujinx/pull/2671#issuecomment-923513823
Hardware decoding also complicates this though, as nVidia's hardware decoding, and software decoding on Android, only return presentation order. So in the end I kept both the current queue and the new map, switching between them based on whether we can use the hack or not.
In addition, this PR tries to speed up decoding in various ways. One thing left out of Yuzu currently is to let the engines run asynchronously. Not only do nvdec and vic run on the same thread, they run inside the service callback thread so games can't queue more commands until nvdec and vic finish decoding potentially multiple frames, which causes large slowdowns, especially videos which play during gameplay. This PR splits nvdec and vic into their own threads so they can in parallel, and also does not block the service thread for command processing.
VIC has received a complete overhaul in order to make it more accurate and support more features. In particular I wanted to get rid of the calls to swscale which we were using for frame conversion, as they were very slow. This meant supporting the colour conversion matrix inside VIC, and more broadly all of the frame sizing/resizing and potentially alpha blending multiple images together. I haven't seen any games attempt to blend multiple images together, so alpha blending is left as a TODO, but with the new structure the potential is there to add it more easily than previously.
An x86 SIMD path is added for the read/blend/write steps which make up the VIC, which provide huge speedups vs the non-SIMD versions. Currently ARM (Android) does not have this supported, which greatly slows down the performance of the VIC on Android, as I don't have any way to test ARM. If anyone would like to, please implement the NEON versions of the x86 code, it would be hugely beneficial. I tried to document each step of the algorithms to make them as easy as possible to follow.
VP9 software decoding is still slower than is ideal, the Skyward Sword HD intro video for example still has crackling audio due to VIC executing too slowly. If anyone has any ideas for speeding up VIC even more, please let me know.
Closes #11982
Closes #6345
Needs testing: #7051, #7508
Relies on https://github.com/yuzu-emu/ext-windows-bin/pull/49 to build.

Squall-Leonhart commented at 2024-01-24 21:43:

Please fix the missing header and rebase.

samusaran commented at 2024-01-25 09:33:

This PR helps with the rendering of Price of Persia The Lost Crown movies, but it's still not enough to have the perfect result. It seems that keyframes are rendered correctly but the ones that follows does not.

Squall-Leonhart commented at 2024-01-25 17:53:

Include file is out of the required ordering.
#include "video_core/engines/maxwell_3d.h"
+#include "video_core/guest_memory.h"
#include "video_core/host1x/host1x.h"
#include "video_core/host1x/nvdec.h"
#include "video_core/host1x/vic.h"
#include "video_core/memory_manager.h"
-#include "video_core/guest_memory.h"
#include "video_core/textures/decoders.h"

Squall-Leonhart commented at 2024-01-25 17:55:

ack, its more than just that one include

Squall-Leonhart commented at 2024-01-25 17:55:

--- a/src/core/guest_memory.h
+++ b/src/core/guest_memory.h
@@ -193,8 +193,7 @@ public:
GuestMemoryScoped() = delete;
explicit GuestMemoryScoped(M& memory, u64 addr, std::size_t size,
Common::ScratchBuffer<T>* backup = nullptr)
-        : GuestMemory<M, T, FLAGS>(memory, addr, size, backup) {
-    }
+        : GuestMemory<M, T, FLAGS>(memory, addr, size, backup) {}
~GuestMemoryScoped() {
if constexpr (FLAGS & GuestMemoryFlags::Write) {
@@ -205,11 +204,13 @@ public:
if (this->AddressChanged() || this->IsDataCopy()) {
ASSERT(this->m_span_valid);
if constexpr (FLAGS & GuestMemoryFlags::Cached) {
-                    this->m_memory->WriteBlockCached(this->m_addr, this->data(), this->size_bytes());
+                    this->m_memory->WriteBlockCached(this->m_addr, this->data(),
+                                                     this->size_bytes());
} else if constexpr (FLAGS & GuestMemoryFlags::Safe) {
this->m_memory->WriteBlock(this->m_addr, this->data(), this->size_bytes());
} else {
-                    this->m_memory->WriteBlockUnsafe(this->m_addr, this->data(), this->size_bytes());
+                    this->m_memory->WriteBlockUnsafe(this->m_addr, this->data(),
+                                                     this->size_bytes());
}
} else if constexpr ((FLAGS & GuestMemoryFlags::Safe) ||
(FLAGS & GuestMemoryFlags::Cached)) {
diff --git a/src/video_core/host1x/host1x.h b/src/video_core/host1x/host1x.h
index dad48a2..f36ab40 100644
--- a/src/video_core/host1x/host1x.h
+++ b/src/video_core/host1x/host1x.h
@@ -6,8 +6,8 @@
#include "common/common_types.h"
#include "common/address_space.h"
-#include "video_core/host1x/gpu_device_memory_manager.h"
#include "video_core/cdma_pusher.h"
+#include "video_core/host1x/gpu_device_memory_manager.h"
#include "video_core/host1x/syncpoint_manager.h"
#include "video_core/memory_manager.h"
diff --git a/src/video_core/host1x/vic.cpp b/src/video_core/host1x/vic.cpp
index eaee6f0..6900ee4 100644
--- a/src/video_core/host1x/vic.cpp
+++ b/src/video_core/host1x/vic.cpp
@@ -34,11 +34,11 @@ extern "C" {
#include "common/settings.h"
#include "video_core/engines/maxwell_3d.h"
+#include "video_core/guest_memory.h"
#include "video_core/host1x/host1x.h"
#include "video_core/host1x/nvdec.h"
#include "video_core/host1x/vic.h"
#include "video_core/memory_manager.h"
-#include "video_core/guest_memory.h"
#include "video_core/textures/decoders.h"

Squall-Leonhart commented at 2024-01-25 18:34:

/__w/yuzu/yuzu/src/video_core/host1x/ffmpeg/ffmpeg.cpp:309:24: error: no member named 'flags' in 'FFmpeg::Frame'
(m_temp_frame->flags & AV_FRAME_FLAG_INTERLACED) != 0;
~~~~~~~~~~~~~~^
2 warnings and 1 error generated.

FernandoS27 commented at 2024-01-31 15:40:

It's safe to tag as only MacOS and Mingw are failling. Do not merge until this 2 targets have been fixed.

Squall-Leonhart commented at 2024-02-01 02:25:

Regressed Metroid Prime, see #12876

K900 commented at 2024-02-03 12:34:

The codec_internal.h include is not part of the public API, which breaks building with system ffmpeg.

Kelebek1 commented at 2024-02-03 15:26:

The codec_internal.h include is not part of the public API, which breaks building with system ffmpeg.
We know, but FFmpeg unfortunately don't provide a way to get frames in decode order, or to at least prevent it from holding back frames, so this is a workaround which is required to fix some games' videos (My Girlfriend is a Mermaid for example).

K900 commented at 2024-02-03 15:42:

So building with vendored ffmpeg is the only option going forward? If so, the CMake option should probably be removed...

liamwhite commented at 2024-02-07 23:50:

@K900 Do you think it would be worth my time to extract the software h264 decoder from FFmpeg and vendor a copy, instead of using the private API or just not using the private API at all on non-Windows platforms?

K900 commented at 2024-02-08 06:57:

As a distro maintainer, it would be nice to keep the option to build with system ffmpeg, as we trust and control that more, and can quickly ship security fixes, etc. However, I don't really know how difficult it'll be to do, as I'm not super familiar with the code base.

1480653625 commented at 2024-02-23 03:32:

Hi

FearlessTobi commented at 2024-02-27 14:43:

What is the status on this?

[Export of Github issue for yuzu-emu/yuzu. Generated on 2024.02.28 at 10:04:32.]

**Branch:** [__refs_pull_12461_head](https://accord.dravee.dev/Accord/yuzu-mirror/src/branch/__refs_pull_12461_head) > **Labels**: `gpu`, `do-not-merge`, `early-access-merge`, `android-merge` #### <div><img width="50" height="50" src="https://avatars.githubusercontent.com/u/34639600?v=4" width="50"></div>[Kelebek1](https://github.com/Kelebek1) opened issue at [2023-12-24 16:54](https://github.com/yuzu-emu/yuzu/pull/12461): > This is a rework of Nvdec and VIC, primarily VIC, aiming to fix some videos which play out of order, like My Girlfriend Is A Mermaid, and also to speed up decoding where possible. > Nvdec and VIC operate together, nvdec takes in some frame inputs, decodes the frame, and writes the resulting luma/chroma to memory at addresses given the registers. VIC then reads these surfaces, blends them together and performing other compositing features (scaling/rotation/colour conversion/etc), and then writes the composited image back to memory. > Currently, to avoid some extra effort, we just store the resulting frames from nvdec in a queue, and then pop a frame each time VIC is called. This works for the majority of games, but some want the VIC to grab frames out of order relative to nvdec. For example, from My Girlfriend Is A Mermaid: > ``` > Nvdec storing to 0x73D000 > Nvdec storing to 0xA3D000 > Nvdec storing to 0xD3D000 > Nvdec storing to 0x103D000 > Nvdec storing to 0x133D000 > Nvdec storing to 0x163D000 > Nvdec storing to 0x193D000 > Nvdec storing to 0x1C3D000 > VIC reading from 0x73D000 > VIC reading from 0xD3D000 > VIC reading from 0x103D000 > VIC reading from 0xA3D000 > VIC reading from 0x163D000 > VIC reading from 0x193D000 > Nvdec storing to 0x103D000 > ``` > You can see VIC expects to read 0xD3D000 as its second frame to output, but nvdec's second frame was 0xA3D000, and this isn't actually requested by VIC until frame 4. This sort of re-ordering doesn't work using a queue, so instead I've switched this over to a map keyed on the offset, so VIC can find the right frame and correct the frame order. > Unfortunately it's not *that* simple, as we use ffmpeg to decode the frames, we can't make ffmpeg return frames in decode order to fit the offsets, which this strategy requires. That means when we call receive frame on ffmpeg, it can return us a different frame than we expect, and we associate the wrong frames with the wrong offsets, and again read them out of the expected order. As a hacky workaround for this, we implement the same suggestion @jduncanator suggested for Ryujinx: https://github.com/Ryujinx/Ryujinx/pull/2671#issuecomment-923513823 > Hardware decoding also complicates this though, as nVidia's hardware decoding, and software decoding on Android, only return presentation order. So in the end I kept both the current queue and the new map, switching between them based on whether we can use the hack or not. > In addition, this PR tries to speed up decoding in various ways. One thing left out of Yuzu currently is to let the engines run asynchronously. Not only do nvdec and vic run on the same thread, they run inside the service callback thread so games can't queue more commands until nvdec and vic finish decoding potentially multiple frames, which causes large slowdowns, especially videos which play during gameplay. This PR splits nvdec and vic into their own threads so they can in parallel, and also does not block the service thread for command processing. > VIC has received a complete overhaul in order to make it more accurate and support more features. In particular I wanted to get rid of the calls to swscale which we were using for frame conversion, as they were very slow. This meant supporting the colour conversion matrix inside VIC, and more broadly all of the frame sizing/resizing and potentially alpha blending multiple images together. I haven't seen any games attempt to blend multiple images together, so alpha blending is left as a TODO, but with the new structure the potential is there to add it more easily than previously. > An x86 SIMD path is added for the read/blend/write steps which make up the VIC, which provide huge speedups vs the non-SIMD versions. Currently ARM (Android) does not have this supported, which greatly slows down the performance of the VIC on Android, as I don't have any way to test ARM. If anyone would like to, please implement the NEON versions of the x86 code, it would be hugely beneficial. I tried to document each step of the algorithms to make them as easy as possible to follow. > VP9 software decoding is still slower than is ideal, the Skyward Sword HD intro video for example still has crackling audio due to VIC executing too slowly. If anyone has any ideas for speeding up VIC even more, please let me know. > Closes #11982 > Closes #6345 > Needs testing: #7051, #7508 > Relies on https://github.com/yuzu-emu/ext-windows-bin/pull/49 to build. #### <div><img width="50" height="50" src="https://avatars.githubusercontent.com/u/1098176?v=4" width="50"></div>[Squall-Leonhart](https://github.com/Squall-Leonhart) commented at [2024-01-24 21:43](https://github.com/yuzu-emu/yuzu/pull/12461#issuecomment-1908964518): > Please fix the missing header and rebase. #### <div><img width="50" height="50" src="https://avatars.githubusercontent.com/u/290743?v=4" width="50"></div>[samusaran](https://github.com/samusaran) commented at [2024-01-25 09:33](https://github.com/yuzu-emu/yuzu/pull/12461#issuecomment-1909751527): > This PR helps with the rendering of Price of Persia The Lost Crown movies, but it's still not enough to have the perfect result. It seems that keyframes are rendered correctly but the ones that follows does not. #### <div><img width="50" height="50" src="https://avatars.githubusercontent.com/u/1098176?v=4" width="50"></div>[Squall-Leonhart](https://github.com/Squall-Leonhart) commented at [2024-01-25 17:53](https://github.com/yuzu-emu/yuzu/pull/12461#issuecomment-1910709963): > Include file is out of the required ordering. > #include "video_core/engines/maxwell_3d.h" > +#include "video_core/guest_memory.h" > #include "video_core/host1x/host1x.h" > #include "video_core/host1x/nvdec.h" > #include "video_core/host1x/vic.h" > #include "video_core/memory_manager.h" > -#include "video_core/guest_memory.h" > #include "video_core/textures/decoders.h" #### <div><img width="50" height="50" src="https://avatars.githubusercontent.com/u/1098176?v=4" width="50"></div>[Squall-Leonhart](https://github.com/Squall-Leonhart) commented at [2024-01-25 17:55](https://github.com/yuzu-emu/yuzu/pull/12461#issuecomment-1910712379): > ack, its more than just that one include #### <div><img width="50" height="50" src="https://avatars.githubusercontent.com/u/1098176?v=4" width="50"></div>[Squall-Leonhart](https://github.com/Squall-Leonhart) commented at [2024-01-25 17:55](https://github.com/yuzu-emu/yuzu/pull/12461#issuecomment-1910713622): > ``` > --- a/src/core/guest_memory.h > +++ b/src/core/guest_memory.h > @@ -193,8 +193,7 @@ public: > GuestMemoryScoped() = delete; > explicit GuestMemoryScoped(M& memory, u64 addr, std::size_t size, > Common::ScratchBuffer<T>* backup = nullptr) > - : GuestMemory<M, T, FLAGS>(memory, addr, size, backup) { > - } > + : GuestMemory<M, T, FLAGS>(memory, addr, size, backup) {} > ~GuestMemoryScoped() { > if constexpr (FLAGS & GuestMemoryFlags::Write) { > @@ -205,11 +204,13 @@ public: > if (this->AddressChanged() || this->IsDataCopy()) { > ASSERT(this->m_span_valid); > if constexpr (FLAGS & GuestMemoryFlags::Cached) { > - this->m_memory->WriteBlockCached(this->m_addr, this->data(), this->size_bytes()); > + this->m_memory->WriteBlockCached(this->m_addr, this->data(), > + this->size_bytes()); > } else if constexpr (FLAGS & GuestMemoryFlags::Safe) { > this->m_memory->WriteBlock(this->m_addr, this->data(), this->size_bytes()); > } else { > - this->m_memory->WriteBlockUnsafe(this->m_addr, this->data(), this->size_bytes()); > + this->m_memory->WriteBlockUnsafe(this->m_addr, this->data(), > + this->size_bytes()); > } > } else if constexpr ((FLAGS & GuestMemoryFlags::Safe) || > (FLAGS & GuestMemoryFlags::Cached)) { > diff --git a/src/video_core/host1x/host1x.h b/src/video_core/host1x/host1x.h > index dad48a2..f36ab40 100644 > --- a/src/video_core/host1x/host1x.h > +++ b/src/video_core/host1x/host1x.h > @@ -6,8 +6,8 @@ > #include "common/common_types.h" > #include "common/address_space.h" > -#include "video_core/host1x/gpu_device_memory_manager.h" > #include "video_core/cdma_pusher.h" > +#include "video_core/host1x/gpu_device_memory_manager.h" > #include "video_core/host1x/syncpoint_manager.h" > #include "video_core/memory_manager.h" > diff --git a/src/video_core/host1x/vic.cpp b/src/video_core/host1x/vic.cpp > index eaee6f0..6900ee4 100644 > --- a/src/video_core/host1x/vic.cpp > +++ b/src/video_core/host1x/vic.cpp > @@ -34,11 +34,11 @@ extern "C" { > #include "common/settings.h" > #include "video_core/engines/maxwell_3d.h" > +#include "video_core/guest_memory.h" > #include "video_core/host1x/host1x.h" > #include "video_core/host1x/nvdec.h" > #include "video_core/host1x/vic.h" > #include "video_core/memory_manager.h" > -#include "video_core/guest_memory.h" > #include "video_core/textures/decoders.h" > ``` #### <div><img width="50" height="50" src="https://avatars.githubusercontent.com/u/1098176?v=4" width="50"></div>[Squall-Leonhart](https://github.com/Squall-Leonhart) commented at [2024-01-25 18:34](https://github.com/yuzu-emu/yuzu/pull/12461#issuecomment-1910769457): > ``` > /__w/yuzu/yuzu/src/video_core/host1x/ffmpeg/ffmpeg.cpp:309:24: error: no member named 'flags' in 'FFmpeg::Frame' > (m_temp_frame->flags & AV_FRAME_FLAG_INTERLACED) != 0; > ~~~~~~~~~~~~~~^ > 2 warnings and 1 error generated. > ``` #### <div><img width="50" height="50" src="https://avatars.githubusercontent.com/u/1731197?u=cfaa9b3f59e99f5f7b6d2f7f210e46cfe31defdb&v=4" width="50"></div>[FernandoS27](https://github.com/FernandoS27) commented at [2024-01-31 15:40](https://github.com/yuzu-emu/yuzu/pull/12461#issuecomment-1919365167): > It's safe to tag as only MacOS and Mingw are failling. Do not merge until this 2 targets have been fixed. #### <div><img width="50" height="50" src="https://avatars.githubusercontent.com/u/1098176?v=4" width="50"></div>[Squall-Leonhart](https://github.com/Squall-Leonhart) commented at [2024-02-01 02:25](https://github.com/yuzu-emu/yuzu/pull/12461#issuecomment-1920374382): > Regressed Metroid Prime, see #12876 #### <div><img width="50" height="50" src="https://avatars.githubusercontent.com/u/386765?u=b8b36610c1807bf3be1ced41fded95cc3e3a0d4e&v=4" width="50"></div>[K900](https://github.com/K900) commented at [2024-02-03 12:34](https://github.com/yuzu-emu/yuzu/pull/12461#issuecomment-1925309453): > The `codec_internal.h` include is not part of the public API, which breaks building with system ffmpeg. #### <div><img width="50" height="50" src="https://avatars.githubusercontent.com/u/34639600?v=4" width="50"></div>[Kelebek1](https://github.com/Kelebek1) commented at [2024-02-03 15:26](https://github.com/yuzu-emu/yuzu/pull/12461#issuecomment-1925358776): > > The `codec_internal.h` include is not part of the public API, which breaks building with system ffmpeg. > We know, but FFmpeg unfortunately don't provide a way to get frames in decode order, or to at least prevent it from holding back frames, so this is a workaround which is required to fix some games' videos (My Girlfriend is a Mermaid for example). #### <div><img width="50" height="50" src="https://avatars.githubusercontent.com/u/386765?u=b8b36610c1807bf3be1ced41fded95cc3e3a0d4e&v=4" width="50"></div>[K900](https://github.com/K900) commented at [2024-02-03 15:42](https://github.com/yuzu-emu/yuzu/pull/12461#issuecomment-1925362407): > So building with vendored ffmpeg is the only option going forward? If so, the CMake option should probably be removed... #### <div><img width="50" height="50" src="https://avatars.githubusercontent.com/u/9658600?v=4" width="50"></div>[liamwhite](https://github.com/liamwhite) commented at [2024-02-07 23:50](https://github.com/yuzu-emu/yuzu/pull/12461#issuecomment-1933129532): > @K900 Do you think it would be worth my time to extract the software h264 decoder from FFmpeg and vendor a copy, instead of using the private API or just not using the private API at all on non-Windows platforms? #### <div><img width="50" height="50" src="https://avatars.githubusercontent.com/u/386765?u=b8b36610c1807bf3be1ced41fded95cc3e3a0d4e&v=4" width="50"></div>[K900](https://github.com/K900) commented at [2024-02-08 06:57](https://github.com/yuzu-emu/yuzu/pull/12461#issuecomment-1933460598): > As a distro maintainer, it would be nice to keep the option to build with system ffmpeg, as we trust and control that more, and can quickly ship security fixes, etc. However, I don't really know how difficult it'll be to do, as I'm not super familiar with the code base. #### <div><img width="50" height="50" src="https://avatars.githubusercontent.com/u/82274547?v=4" width="50"></div>[1480653625](https://github.com/1480653625) commented at [2024-02-23 03:32](https://github.com/yuzu-emu/yuzu/pull/12461#issuecomment-1960687364): > Hi #### <div><img width="50" height="50" src="https://avatars.githubusercontent.com/u/20753089?u=4c1e2e5b0b4b5b40b1004b7fe0948d56f0adaf50&v=4" width="50"></div>[FearlessTobi](https://github.com/FearlessTobi) commented at [2024-02-27 14:43](https://github.com/yuzu-emu/yuzu/pull/12461#issuecomment-1966707544): > What is the status on this? > ------------------------------------------------------------------------------- > [Export of Github issue for [yuzu-emu/yuzu](https://github.com/yuzu-emu/yuzu). Generated on 2024.02.28 at 10:04:32.]
vic: ensure in-bounds accesses for accelerated ops
Some checks failed
yuzu-ci / transifex (pull_request) Has been cancelled
yuzu-ci / reuse (pull_request) Has been cancelled
codespell / Check for spelling errors (pull_request) Has been cancelled
yuzu verify / verify format (pull_request) Has been cancelled
yuzu verify / test build (pull_request) Has been cancelled
yuzu verify / test build-1 (pull_request) Has been cancelled
yuzu verify / test build-2 (pull_request) Has been cancelled
yuzu verify / test build (macos) (pull_request) Has been cancelled
yuzu verify / test build (windows, msvc) (pull_request) Has been cancelled
yuzu verify / android (pull_request) Has been cancelled
a84e8e26fa
Some checks failed
yuzu-ci / transifex (pull_request) Has been cancelled
yuzu-ci / reuse (pull_request) Has been cancelled
codespell / Check for spelling errors (pull_request) Has been cancelled
yuzu verify / verify format (pull_request) Has been cancelled
yuzu verify / test build (pull_request) Has been cancelled
yuzu verify / test build-1 (pull_request) Has been cancelled
yuzu verify / test build-2 (pull_request) Has been cancelled
yuzu verify / test build (macos) (pull_request) Has been cancelled
yuzu verify / test build (windows, msvc) (pull_request) Has been cancelled
yuzu verify / android (pull_request) Has been cancelled
This pull request can be merged automatically.
This branch is out-of-date with the base branch
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin __refs_pull_12461_head:__refs_pull_12461_head
git switch __refs_pull_12461_head

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch master
git merge --no-ff __refs_pull_12461_head
git switch __refs_pull_12461_head
git rebase master
git switch master
git merge --ff-only __refs_pull_12461_head
git switch __refs_pull_12461_head
git rebase master
git switch master
git merge --no-ff __refs_pull_12461_head
git switch master
git merge --squash __refs_pull_12461_head
git switch master
git merge --ff-only __refs_pull_12461_head
git switch master
git merge __refs_pull_12461_head
git push origin master
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Accord/yuzu-mirror!12461
No description provided.