This commit introduces the `CommandExecutor` which is responsible for creating and orchestrating a Vulkan command graph comprising of `CommandNode`s that construct all the objects required for rendering. As a result of the infrastructure provided by `CommandExecutor`, `ClearBuffers` could be implemented and be appropriately utilized.
A bug regarding scissors was also determined and fixed in the PR, the extent of them were previously inaccurate and this has now been fixed.
Note: We don't synchronize any textures from the guest for now as this would override the contents on the host, this'll be fixed with the appropriate write tracking but it also results in a black screen for anything that writes to FB
This commit fixes a major issue with command buffer allocation which would result in only being able to utilize a command buffer slot on the 2nd attempt to use it after it's freed, this would lead to a significantly larger amount of command buffers being created than necessary. It also fixes an issue with the command buffers not being reset after they were utilized which results in UB eventually.
Another issue was fixed with `FenceCycle` where all dependencies are only destroyed on destruction of the `FenceCycle` itself rather than the function where the `VkFence` was found to be signalled.
This commit implements a filter by type for any validation layer output, this allows filtering out any logs which may be unnecessary and additionally triggering a breakpoint as required.
An issue concerning the `NDEBUG` flag never being set was fixed, it's now supplied as a release compiler flag. The issue can manifest itself by always relying on a validation layer even though it shouldn't on release, this is why the validation layer was mistakenly disabled entirely previously by using `#ifndef` rather than `#ifdef`.
An issue with the initial layout of a texture being supplied as neither `VK_IMAGE_LAYOUT_UNDEFINED` or `VK_IMAGE_LAYOUT_PREINITIALIZED` was fixed, these cases are now handled by transitioning to those layouts after creating the image rather than supplying it within `initialLayout`.
Another issue was fixed regarding not maintaining a transformation after a surface has been destroyed and recreated existed and manifested itself when the user would go out of the app and come back in, they would see the surface having an identity transformation rather than the desired one.
Fixes bugs with the Texture Manager lookup, fixes `RenderTarget` address extraction (`low`/`high` were flipped prior), refactors `Maxwell3D::CallMethod` to utilize a case for the register being modified + preventing redundant method calls when no new value is being written to the register, and fixes the behavior of shadow RAM which was broken previously and would lead to incorrect arguments being utilized for methods.
Implement the groundwork for the texture manager to be able to report basic overlaps and be extended to support more in the future. The Maxwell3D registers `RenderTargetControl`, `RenderTarget` and a stub for `ClearBuffers` were implemented.
A lot of changes were also made to `GuestTexture`/`Texture` for supporting mipmapping and multiple array layers alongside significant architectural changes to `GuestTexture` effectively disconnecting it from `Texture` with it no longer being a parent rather an object that can be used to create a `Texture` object.
Note: Support for fragmented CPU mappings hasn't been added for texture synchronization yet
Utilize Boost Container's `small_vector` for optimizing allocations, fix certain implicit casting issues and make `ILogger` not output an additional newline in the log when the application supplies one at the end of the log
The format provided in `GraphicBuffer` can be misleading and is supplied as `None` by the Deko3D Swapchain, it instead supplies the real format in the `NvGraphicHandle` which we now utilize instead of the one in `GraphicBuffer`.
KTransferMemory needs to be reset to RW on destruction unlike KSharedMemory which is simply freed on destruction, not emulating this behavior accurately leads to `deko_examples` from `switch-examples` to lead to a SEGFAULT on selecting an example as it expects the memory to be R/W while it ends up being freed instead
The unique pointer to a device in the map was simply reset rather than deleting the entry from the map, this resulted in the device not being properly closed and when the device was reopened then the `emplace` was a NOP as the entry already existed. This resulted in a `nullptr` dereference down the line when an application attempted to issue an IOCTL to a device that was previously closed and reopened. This is known to occur in Deko3D as it recreates the context when loading an example which includes closing and reopening devices.
A hotfix for a nvdrv bug where an IOCTL with no input/output buffers would crash and a major `nvmap` bug which broke the `FromId` IOCTL as it didn't write back the handle ID, another minor bug existed in `nvhost` where the `ZCullGetInfo` IOCTL was `INOUT` rather than `OUT`.
A bug with NACPs was also fixed caused by incorrect padding for the `NacpData` structure which resulted in the `saveDataOwnerId` member being read incorrectly and as a result the save data folder being incorrect.
Co-authored-by: artem8086 <artemsvyatoha@gmail.com>
Swapped out the usages of frozen constexpr unordered maps for switch statements, which are very likely to be turned into jump tables given the nature of the enums used, resulting in better performance than a map
Unlike `ListPreference`, this preference class uses integers as its values instead of strings, avoiding unnecessary casting. It also doesn't require an array for values: in that case it will be using the clicked entry position as its value.
Using a u32 for the loop index prevents masking on all increments,
giving a moderate performance increase.
Passing methods as u32 parameters and stopping subChannel being passed
gives quite a significant increase when combined with the inlining
allowed by subchannel based engine selection.
The implementation of GPU channels and Host1X channels will be split up
as it allows a much cleaner implementation and less undefined behaviour
potential.
This will be required later for NVDEC/SMMU support and fixes many
significant issues in the previous implementation.
Based off of my 2.0.0/12.0.0 nvdrv REs.
The syncpoint manager has beeen given convinience functions for fences
which remove the need to access the raw id/threshold most of the time
and various accuracy fixes and cleanups to match HOS 12.0.0 have also
been done.
Implements the 'csrng:' service using C++ <random>'s Mersenne Twister, this does make it insecure for cryptographic purposes but it is pointless to attempt to do this regardless as we cannot ensure that the guest will run in a secure environment which cannot be mutated by an attacker. Used by Prison Princess, Pokemon Cafe Mix, Paint your Pet and more.
Encountered in 不如帰大乱 when `HOS-3` is awoken at the same time as `HOS-0` called `SvcSetThreadCoreMask` resulting in a deadlock where `HOS-0` owns `HOS-3`'s `coreMigrationMutex` while `HOS-3` owns the core mutex with the both of them attempting to lock the other mutex
We've moved from using an AAR for Mbed TLS to a submodule as the AAR was packaged manually and used from a local repository which ended up being very hacky and resulted in Linter errors, it could also not be updated with ease as it would need to be repackaged. All of these issues have been solved by moving to a git submodule tied to the official Mbed TLS GitHub repository.
Sticky transforms have been stubbed, as they are on HOS/Android. Certain titles like Xenoblade Chronicles end up setting the sticky transform even if it doesn't do anything, as a result of this we cannot throw an exception for it and stub it without an exception (Aside from the cases where the value isn't recognized).
The following GraphicBufferProducer transactions were implemented:
* `SetBufferCount`
* `DetachBuffer`
* `DetachNextBuffer`
* `AttachBuffer`
It should be noted that `preallocatedBufferCount` (previously `hasBufferCount`) and `activeSlotCount` were adapted accordingly with how they were effectively the same value as all active buffers were preallocated prior but now there can be a non-preallocated active slot.
Additionally, a bug has been fixed where `SetPreallocatedBuffer` has the graphic buffer as an optional argument whereas it was treated as a mandatory argument prior and could lead to a SEGFAULT if an application were to not pass in a buffer.
VI/IHOSBinder suffered from major inaccuracies in their function due to being quickly thrown together initially with little concern for accuracy, this has now been fixed with them being substantially more accurate now.
`ENUM_STRING` now has a unified implementation in <common/macros.h> with a documented format and can be used throughout the codebase.
A major performance regression was added in the Host1X Syncpoint revamp as it did a syscall if there were any waiters during `Increment` even if they would just be woken up and go back to sleep as the threshold wasn't hit. It has now been optimized to only do a wake if any waiting thread needs to be awoken.
There was also a bug concerning increment where it would perform actions corresponding to the previous increment rather than the current one which has also been fixed.
We used instantaneous values for FPS previously which led to a lot of variation in it and the inability to determine a proper FPS value due to constant fluctuations. All FPS values are now averaged to allow reading out a stable value and a deviation statistic has been added for the frame-time to judge judder and frame-pacing which allows for a significantly better measure of overall performance. The formatting for all the floating-point numbers is now fixed-point to prevent shifting of position due to decimal digits becoming 0.
Support for the following parameters was added to `QueueBuffer`:
* Earliest Present Timestamp
* Swap Interval
* Crop
* Scaling Mode
* Transform
* Frame ID (Not returned to guest yet)
We utilize ANativeWindow APIs directly to achieve all of this in an efficient manner since HWC will be used directly for it, we do plan to introduce Vulkan equivalents for all of these operations later down the line for a port to non-Android platforms.
We had issues when combining host and guest presentation since certain configurations in guest presentation such as double buffering were very unoptimal for the host and would significantly affect the FPS. As a result of this, we've now made host presentation have its own presentation textures which are copied into from the guest at presentation time, allowing us to change parameters of the host presentation independently of the guest.
We've implemented the infrastructure for this which includes being able to create images from host GPU memory using VMA, an optimized linear texture sync and a method to do on-GPU texture-to-texture copies.
We've also moved to driving the V-Sync event using AChoreographer on its on thread in this PR, which more accurately encapsulates HOS behavior and allows games such as ARMS to boot as they depend on the V-Sync event being signalled even when the game isn't presenting.
This commit reworks the `Texture` class to include a Vulkan Image backing that can be optionally owning or non-owning and swapped in with consideration for Vulkan image layout, it also adds CPU-sided synchronization for the texture objects with FenceCycle. It also makes the appropriate changes to `PresentationEngine` and `GraphicBufferProducer` to work with the new `Texture` class while setting the groundwork for supporting swapchain recreation. It also fixes a log in `IpcResponse` and improves the display mode selection algorithm by further weighing refresh rate.
Implements a wrapper over fences to track a single cycle of activation, implement a Vulkan memory manager that wraps the Vulkan-Memory-Allocator library and a command scheduler for scheduling Vulkan command buffers
This commit makes GraphicBufferProducer significantly more accurate by matching the behavior of AOSP alongside mirroring the tweaks made by Nintendo.
It eliminates a lot of the magic structures and enumerations used prior and replaces them with the correct values from AOSP or HOS.
There was a lot of functional inaccuracy as well which was fixed, we emulate the exact subset of HOS behavior that we need to. A lot of the intermediate layers such as GraphicBufferConsumer or Gralloc/Sync are not emulated as they're pointless abstractions here.
This commit adds in VkSurface/VkSwapchain initialization and recreation. It also adapts GraphicsBuffferProducer and Texture to fit in with those changes but it doesn't yet implement presenting those buffers nor uploading guest buffers onto the host.
Vulkan Device initialization is handled now, it supports required extensions but support for optional extensions/features/properties will come in later when we require those. In addition, we now correctly report the version of Skyline to Vulkan which can be accessed from debugging tools.
There's also a minor change regarding the search pattern for `SkylineLibraries` which now only searches in headers of libraries and it also explicitly excludes the redundant `vulkan.hpp` from the `Vulkan-Headers` repository.
The GPU class has been extended in this for Vulkan initialization, this is done to the point of initializing the instance alongside loading in `VK_LAYER_KHRONOS_validation` which is also now packed into all Debug APKs for Skyline. In addition, `VK_EXT_debug_report` is also initialized and it's output is piped directly into the Logger.
A minor change regarding the type of the `Fps` and `Frametime` globals was changed to `skyline::i32`s which is a more suitable type due to those having a smaller chance of overflowing while being signed as Java doesn't have unsigned integral types.
As both of these are in the same memory segment they have no individual
alignment requirements, this created a bug in
にゃんらぶ~私の恋の見つけ方~ where the data segment would be larger
than the game expected and invalid command line arguments would be read.
armed.
It was discovered during testing of 'Hatsune Miku Project DIVA: Mega Mix'
that if a thread was starting while preemption was being enabled a NULL
pointer dereference could occur in the timer_settime call as
timer_create may not have been called yet.
This is used by games before calling into nvdec in order to clock up the
HW module, it can also be used to request a RAM frequency. Since we
obviously don't emulate the hardware down to this level a basic stub
that provides the correct reponses is enough.
Fixes a crash on first level of Super Mario Odyssey.
We used a custom version of Vulkan-Hpp which split the files a lot prior to avoid any developers needing to manually set IDE settings for IntelliJ to work but this wasn't practical due to how it required modifications to Vulkan-Hpp's generator which would make maintenance extremely difficult. It was determined that we should just add the requirement for changing the IDE settings and use Vulkan-Hpp directly.