* Update sceKernelMemoryPoolExpand
Hardware tests show that this function is basically the same as sceKernelAllocateDirectMemory, with some minor differences.
Update the memory searching code to match my updated AllocateDirectMemory code, with appropriate error conditions.
* Update MemoryPoolReserve
Only difference between real hw and our code is behavior with addr = 0.
* Don't coalesce PoolReserved areas.
Real hardware doesn't coalesce them.
* Update PoolCommit
Plenty of edge case behaviors to handle here.
Addresses are treated as fixed, EINVAL is returned for bad mappings, name should be preserved from PoolReserving, committed areas should coalesce, reserved areas get their phys_base updated
* Formatting
* Adjust fixed PoolReserve path
Hardware tests suggest this will overwrite all VMAs in the range. Run UnmapMemoryImpl on the full area, then reserve. Same logic applies to normal reservations too.
Also adjusts logic of the non-fixed path to more closely align with hardware observations.
* Remove phys_base modifications
This can be handled later. Doing the logic properly would likely take work in MergeAdjacent, and would probably need to be applied to normal dmem mappings too.
* Use VMAHandle.Contains()
Why do extra math when we have a function specifically for this?
* Update memory.cpp
* Remove unnecessary code
Since I've removed those two asserts, these two lines of code effectively do nothing.
* Clang
* Fix names
* Fix PoolDecommit
Should fix the address space regressions in UE titles on Windows.
* Fix error log
Should make the cause of this clearer?
* Clang
* Oops
* Remove coalesce on PoolCommit
Windows makes this more difficult.
* Track pool budgets
If you try to commit more pooled memory than is allocated, PoolCommit returns ENOMEM.
Also fixes error conditions for PoolDecommit, that should return EINVAL if given an address that isn't part of the pool.
Note: Seems like the pool budget can't hit zero? I used a <= comparison based on hardware tests, otherwise we're able to make more mappings than real hardware can.
* Reduce bitfield size
Linux compilers automatically convert this, Windows not so much.
* Static assert for VirtualQueryInfo struct size
Since compilers can be weird, having a static assert for this will be helpful.
Granted, this probably wont need changing after this PR.
* Fix VirtualQuery behavior on low addresses.
* Fix VirtualQuery struct
Somewhere in our BitField and array use, the size of our VirtualQuery struct became larger than the struct used on real hardware.
Fixing this fixes some data corruption visible in the name parameter during my tests.
* Default name to anon
On real hardware, nameless mappings are given the name "anon:address" where address appears to be the address that made the memory call.
For simplicity sake, I'll stick to the name "anon" for now.
* Place an upper bound on returns from SearchFree
Right now, this upper bound is set based on the limitations of our GPU buffer cache and page table.
Someone with more experience in that area of code should probably fix that at some point.
* More anons
* Clang
* Fix name in sceKernelMapNamedDirectMemory
* strncpy instead of strcpy
Hardcoded the constant size for now, I need to review how real hardware behaves here to determine if anything else is necessary for this to be accurate.
* Fix name behavior
All memory naming functions restrict the name size to a 31 character limit, and return `ORBIS_KERNEL_ERROR_ENAMETOOLONG` if that limit is exceeded.
Since this value is constant for all functions involving names, I've defined it as a constant in kernel's memory.h, and used that in place of any hardcoded 32 character limits.
* Error logging
Hopefully this helps in catching the UFC regression?
* Increase address space upper bound
Probably needs heavy testing, especially on Mac/Windows.
This increases the address space, as needed to accommodate strange memory behaviors seen in UFC.
* VirtualQuery fix
Due to limitations of certain platforms, we initialize our vma_map with 3 separate free mappings.
As such, we need to use a while loop here to accurately query mappings with high addresses
* Fix mappings to high addresses
The PS4's GPU can only handle 40bit addresses. Our texture cache and buffer cache were designed around these limits, and mapping to higher addresses would cause segmentation faults and access violations.
To fix these crashes, only map to the GPU if the mapping is fully contained within the address space the GPU should access.
I'm open to suggestions on how to make this cleaner
* Revert "Increase address space upper bound"
This reverts commit 3d50eeeebb.
* Revert VirtualQuery while loop
Windows wasn't happy with this, again.
Will try to debug and properly fix this when I have a good chance.
* Fix asserts
FindVMA, due to the way it's programmed, never actually returns vma_map.end(), the furthest it ever returns is the last valid memory area. All those asserts we involving vma_map.end() never actually trigger due to this.
This commit removes redundant asserts, adds messages to asserts that were lacking them, and fixes all asserts designed to detect out of bounds memory accesses so they actually trigger.
I've also fixed some potential memory safety issues.
* Proper error behavior in QueryProtection
Might as well handle this properly while I'm here.
* Clang
* More information about ReserveVirtualRange results
Should help debug issues like the one in The Order: 1886 (CUSA00076)
* Fix assert message
* Update assert message
Extra space
* Fix my bug
Oh hey, finally something that's my fault.
* Fix rasterizer unmaps
Should use adjusted_size here, otherwise we could unmap too much.
Thanks to diegolix29 for spotting this.
* Fix edge case in MapMemory
Code comments explain everything.
This should fix some memory asserts.
* Fix fix
Avoid running the code path if it's unnecessary, since there are many additional edge cases to handle when the VMA map is small.
* Fix fix fix
Should prevent infinite loops, haven't tested properly yet though.
* Split logging for inputs and out_addr in ReserveVirtualRange
Addresses review comments.
We do this in order to be able to actually fit in all possible values from AmdGpu::NumberConversion.
Fixes gcc compiler warnings:
warning: ‘Shader::PsColorBuffer::num_conversion’ is too small to hold all values of ‘enum class AmdGpu::NumberConversion’
* Fix module map addresses
Most modules are mapped starting at 0x800000000, with no gaps between mappings.
* Hardcode hardware accurate base address
Looking at our address space, all platforms will have this base address mapped, so there shouldn't be any problem in using it.
* Clang
* Swap module mapping to NoFlags, remove offset code
Since real hardware has no gap between module mappings, the Fixed flag is just an annoyance to work around, and has no impact on the actual mappings.
Swapping the module mappings to use flags NoFlags instead simplifies our code slightly.
* Fix module mapping names
On real hardware, the file extension is part of the mapping name. Easiest way to manage this is to swap the name to be `file.filename().string()` instead of `file.stem().string()`
* Fix patches
Completely missed this, whoops.
* Proper handling of whence 3 & 4
* Accurate directory handling in open
Directories can be opened, and can be created in open, these changes should handle that more accurately.
* Mount /app0 as read only
On real hardware, it's read only.
* Proper directory flag handling.
Even when directory is specified, it will still succeed to open non-directories.
* Check for read only directories
* Earlier ro check in posix_rmdir
Hardware tests suggest these checks are in a different order
* Clear temp folder on boot
My tests rely on this, and some games do too.
Two birds with one stone
* Clang
* Add missing DeleteHandle calls
Whoops
* Final flags adjustment in sceKernelOpen
All my current tests are now hardware accurate.
* Fix truncates
Host ftruncate consistently fails on EINVAL, I'll need to test if this issue affected Windows too.
* Windows hacks
Windows is more limiting about how folders are opened and things like that. For now, pretend these calls didn't error.
Also fixes compilation for Windows
* Final touch-ups
After expanding my test suite further, I found a couple more edge cases that needed addressing.
Bloodborne audio is still broken, I'll look into that soon.
* Remove hacky read-only behavior in posix_stat
Bloodborne apparently uses the mode parameter here when querying it's audio files, and the mode we returned led to it disabling audio entirely.
* Clang
* Cleaner code
* Combine fsync and sync flags
According to FreeBSD docs, the "sync" flag is synonymous with the fsync flag, and is only included to meet the POSIX spec.
* Log if any currently unhandled flags are encountered.
These are rare and probably not too important, but log a warning when they're seen.
* Update file_system.cpp
* Update file_system.cpp
* Clang
* Revert truncate fix
Using ftruncate works fine after moving the call to before the proper file opening code.
* Truncate before open
Open the file as read-write, then try truncating.
This fixes read | truncate flag behavior on Windows.
* Slightly adjust check for invalid flags
Any open call with invalid flags should return EINVAL, regardless of other errors parameters might cause.
* New translations en_us.ts (Vietnamese)
* New translations en_us.ts (Vietnamese)
* New translations en_us.ts (Vietnamese)
* New translations en_us.ts (Vietnamese)
* shader_recompiler: Add lowering pass for when 64-bit float is unsupported.
* shader_recompiler: Fix PackDouble2x32/UnpackDouble2x32 type.
* shader_recompiler: Remove extra bit cast implementations.
* The default linker which happens to be BFD in Ubuntu 24.04 does not support Clang's ThinLTO which CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON tries to enable.
* Using mold linker fixes this and reduces build time a bit.
* For consistency reasons we enable mold linker for GCC builds aswell.
* Fix GetModule exception
Simple mistake
* Prevent OOB writes in add_segment
Due to mistakes in our linker logic, OpenOrbis' libSceFios2 causes OOB writes here.
While the ideal solution would be to fix the erroneous behavior, the best I'm capable of right now is just preventing the OOB writes.
* Implement sceKernelGetModuleInfo, sceKernelGetModuleInfoInternal, sceKernelGetModuleList
These are implemented based on hardware observations and a homebrew sample made by red_prig. I've yet to test what error cases can show up.
* Clang
* Accurate error returns
If there are more modules than provided space, then return kernel ENOMEM.
If either handles or out_count are null, return kernel EFAULT.
* Accurate error checks in ModuleInfo functions
* Clang
* Readable VideoOutEvent data packing
Inspired by the work of former shadPS4 devs and mostly based on red_prig's current code.
* Apply DceData struct to sceVideoOutGetEventCount
Makes the code easier to read
* Update equeue.h
* Update main.cpp
* Update equeue.h
* Proper struct names
* Fix hint mask
Thanks to red_prig for catching my mistake here.
* Clang
* Fix header discrepancy
* ci: Bump Clang to 19 for Linux builds
* PR #2434 was intended to bump Clang to 19. In reality it only made sure that clang-format-19 is being used and that the shadPS4 codebase can be compiled with Clang 19.
This PR makes sure that Clang 19 is actually being used for Linux builds which makes sense since we use Clang 19 for Windows builds already (Since Visual Studio 17.13 Clang 19 is being shipped).
* ci: Use noble variant of LLVM repository
* shadPS4 has been using Ubuntu 24.04 runners for some time now. This commit makes sure the correct LLVM repository is being used.
* Some sysmodules inconsistencies fixed. Based on Visual studio flags if they are irrelevant lmk
* Suggestions - info passed to sceKernelGetModuleInfoForUnwind and if name field matches it gets zeroed
* Final suggestions
* reverting OrbisModuleInfoForUnwind and modifing header.
* Implement sceImeDialogGetPanelSize
* Fix header
* Clang
* Adjust values that are different from Ime
* Add original sizes as comments
* clang
* At this point half of the PR is from squidbus, and I'm just typing out what they say
---------
Co-authored-by: squidbus <175574877+squidbus@users.noreply.github.com>