aboutsummaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
* video_core: accept an empty Streamline device-extension listDuck9127 hours1-5/+4
| | | | | | | | | | | Streamline may report that DLSS needs no extra device extensions. The check required a non-empty list, so that result counted as "extensions unavailable": Streamline was stopped and FSR 3.1 used. Only require that every listed extension is supported. Found by CodeRabbit review. Assisted-by: Claude Opus 5.5 (implementation) Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com>
* yuzu: bound the zip directory reads in the DLSS downloadDuck9127 hours1-2/+7
| | | | | | | | | | | | | | | The central-directory parser trusted each entry's name, extra and comment lengths and the Zip64 extra field's length, so a malformed directory could make it read past the downloaded buffer. The data comes from NVIDIA's GitHub release over TLS and the saved files are signature-checked, so the risk is low. Stop with an error when an entry runs past the directory, and read Zip64 fields only inside their record. Found by CodeRabbit review. Assisted-by: Claude Opus 5.5 (implementation) Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com>
* video_core, yuzu: write NVIDIA DLSS file paths to logs as UTF-8Duck9127 hours2-13/+18
| | | | | | | | | | | | | | | The Streamline start-up and DLSS download code formatted paths with std::filesystem::path::string(), which on MSVC converts to the active code page and throws when a character has no mapping there, for example a user name in another script under %APPDATA%. The start-up log runs inside the renderer's constructor, which only catches vk::Exception, so such a user would crash at game start with the setting on. Use Common::FS::PathToUTF8String for every path in these logs and messages. Found by CodeRabbit review. Assisted-by: Claude Opus 5.5 (implementation) Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com>
* video_core: clear the DLSS output when Streamline writes nothing to itDuck9127 hours1-0/+39
| | | | | | | | | | | | | | | The upscaler records its work on the worker thread and reports success once it is queued. When Streamline then rejects the DLSS options, gives no frame token or fails the evaluation, nothing is written to the output image, but the caller still draws it into the game's image that frame: undefined contents after a resize, the previous frame otherwise. FSR 3.1 takes over from the next frame. Clear the output on those paths, with barriers around the clear, so that frame is black instead. Found by CodeRabbit review. Assisted-by: Claude Opus 5.5 (implementation) Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com>
* yuzu: show NVIDIA's DLSS files in the Graphics tab and fetch them from NVIDIADuck9127 hours5-2/+604
| | | | | | | | | | | | Under the NVIDIA DLSS checkbox, a panel says whether the Streamline loader and DLSS were found and which versions, with "Open Folder" and a link to NVIDIA's Streamline releases. When files are missing, "Download from NVIDIA" takes only those files out of NVIDIA's Streamline 2.14.16 release zip on GitHub with HTTP range requests (about 1 MB for the loader, 32 MB with DLSS, of the 276 MB zip), after showing the Streamline and DLSS licence texts from the release for acceptance. Each file's CRC and signature are checked before it is saved to the user folder's "streamline" folder. Assisted-by: Claude Opus 5.5 (implementation) Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com>
* video_core: NVIDIA DLSS through NVIDIA Streamline in place of a game's DLSSDuck9127 hours20-17/+1271
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Adds a Graphics setting, "Use NVIDIA DLSS in place of a game's DLSS" (nvidia_dlss, off by default). When it is on, in Windows builds configured with EGLANTINE_STREAMLINE_SDK, the evaluation Eglantine already replaces with FSR 3.1 goes to NVIDIA DLSS on GeForce RTX cards, with the same inputs (colour, depth, motion vectors, jitter). When DLSS can't run, FSR 3.1 runs as before. Only Streamline's MIT-licensed headers are compiled in; nothing of NVIDIA's is linked or shipped. At run time Eglantine looks for sl.interposer.dll in the user folder's "streamline" folder (or EDEN_STREAMLINE_DIR, or "streamline" next to the executable), checks its Streamline signature and starts Streamline with manual hooking. Streamline's plugins come from that folder or the NVIDIA app's downloads. DLSS itself is nvngx_dlss.dll in the same folder, else the newest DLSS 310 or later that the NVIDIA app has downloaded, checked for NVIDIA's Authenticode signature and copied as streamline/nvidia-app/nvngx_dlss.dll. Like other tools that call DLSS outside a game, it uses its own fixed project id with the custom engine type. - Preset K for all modes (EDEN_NX2_DLSS_PRESET overrides it): the default Performance model (M) and L draw thin dark horizontal lines in some frames at 2x resolution scale; K doesn't. - HDR input with auto exposure; the mode follows the render/output ratio. - Buffer device address stays enabled when DLSS needs it, for DLSS only. - The upscaler waits for the device instead of submitting when it is destroyed: by then the game's channels are released, and a submit read the state tracker's stale flags (a crash when stopping a game). With the setting off, or in builds without the SDK path (the setting is hidden there), nothing changes. Testing: Windows 11, RTX 5080, Fire Emblem: Fortune's Weave docked at 1x (720p -> 1440p) and 2x (1440p -> 2880p), CLI runs and GUI play, stopping and restarting games with DLSS on. Not tested on other GPUs or games. Assisted-by: Claude Opus 5.5 (implementation, debugging) Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com>
* video_core: read the framebuffer before recording the upscaled-output blitDuck9127 hours1-7/+11
| | | | | | | | | | | | | | | BlitColor(VkImageView, VkImage, ...), which draws FSR 3.1's output into the game's DLSS output, captured the Framebuffer pointer and read its render pass, handle and size on the worker thread. The pointer points into the texture cache's framebuffer slots, which can be reallocated before the worker records the command, so the render pass could begin with a stale or null render pass and framebuffer. FSR 3.1 records quickly enough that this rarely shows; with a slower first evaluation (NVIDIA DLSS creating its feature) it crashed in vkCmdBeginRenderPass at the first evaluation in every run. Read the three values on the calling thread and capture those instead. Nothing else changes. Assisted-by: Claude Opus 5.5 (debugging, implementation) Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com>
* tests: compare the socket receive count without a sign mismatchkraibse11 hours1-1/+1
| | | | | | | Recv reports a signed int count and payload.size() is size_t, which trips -Werror=sign-compare and stops the tests target from building. Assisted-by: DeepSeek V4.1 Flash (diagnosis and patch)
* tests: give the descriptor table mocks a GetPointer hookkraibse11 hours1-0/+10
| | | | | | | | | | | DescriptorTable::Read calls MemoryManager::GetPointer for entries that fall inside a single page, which neither mock in this test implemented, so the template failed to instantiate and the tests target stopped building. Return nullptr from both mocks so the tests keep exercising the generic ReadBlockUnsafe path they are written for. Assisted-by: DeepSeek V4.1 Flash (diagnosis and patch)
* video_core: cut per-draw work on the GPU back thread in crowded scenes (#374)Duck17 hours2-3/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * video_core: demote the texture cache's per-draw debug logs to trace The invalid sampler and image view index messages fire for unused binding slots on every draw. Filtered LOG_DEBUG messages still cost a call and argument packing: in a Fire Emblem: Fortune's Weave city scene (about 2,100 draws per frame) they were 3.1% of the GPUBack thread's samples. LOG_TRACE compiles them out of release builds. Assisted-by: Claude Opus 5.5 (profiling, porting and drafting) Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com> * texture_cache: read a descriptor with one page lookup DescriptorTable::Read runs for every texture and sampler of every draw, and it read each 32-byte TIC/TSC entry through the generic ReadBlockUnsafe page walk. In a Fire Emblem: Fortune's Weave city scene (about 2,100 draws per frame) that was 5.0% of the GPUBack thread's samples. An entry within one page is contiguous in host memory, so it is now a single page lookup and memcpy. Entries that cross a page and pages without host memory still take the block read, so unmapped and unbacked entries still read as zero. The same change in another Eden-based build cut these reads from 6.4% to 0.4% of its GPU thread. Assisted-by: Claude Opus 5.5 (profiling, porting and drafting) Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com> --------- Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com>
* ci: revert Android release buildsJonas17 hours1-1/+1
| | | | | | | | Revert the Android APK build and release publication introduced by #360, and restore the default Android application ID. Automated Android releases are paused while support issues are addressed. AI disclosure: This commit message was written by AI and does not comply with the repository AI policy requirement that commit messages be human-written. Assisted-by: GPT-6 (prepared the revert and wrote this commit message)
* nx2: fewer render pass splits on tiled GPUs, log failed GPU waits (Pokopia) ↵Alex18 hours2-2/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | (#361) * buffer_cache: don't end the render pass after mapped buffer uploads Every upload set any_buffer_uploaded, and the next draw or dispatch then recorded a transfer-to-shader barrier outside the render pass. On Vulkan the uploads are mapped: each copy either records its own barriers (CopyBuffer with barrier set) or goes to the upload command buffer, which ends with a barrier before the frame's commands run. The extra barrier only ended the render pass. On tiled GPUs every such split writes the attachments out and reads them back. Pokopia's first gameplay scene had ~50 of these splits a frame. Without them, an M3 MacBook Air (MoltenVK, 1x docked) goes from ~35 to ~29.5 ms of GPU time a frame and from 28.5 to 32 fps. OpenGL uploads immediately and keeps the barrier. Assisted-by: Claude Opus 5.5 (profiling, implementation and commit message) * vulkan: log a failed GPU wait before it ends the process When the device is lost, vkWaitSemaphores in MasterSemaphore::Wait returns VK_ERROR_DEVICE_LOST and the exception goes uncaught on the fence thread or the GPU thread, so the process aborts without a line in the log: ReportLoss is only reached from submit and present. A Pokopia crash on macOS left the log ending a second before the abort, with no hint that the GPU was lost. Log the wait's result before rethrowing. On macOS, MoltenVK prints the Metal reason (a GPU hang or page fault) to stderr only. Assisted-by: Claude Opus 5.5 (diagnosis, implementation and commit message)
* common: measure the TSC only on CPUs without CPUID leaf 0x15 (#373)Duck18 hours1-2/+4
| | | | | | | | | | | | | | | | | The fallback that measures the TSC rate when the CPU reports none was meant for AMD, which has no leaf 0x15 at all. It also caught Intel CPUs that have the leaf but report a crystal frequency of 0 (Coffee Lake, e.g. the i5-9400F) and moved them from the OS clock to the measured RDTSC clock. With the same fallback in another Eden-based build, an i5-9400F crashed about 3.5 s after launch; limiting the fallback to CPUs without the leaf fixed it for that tester. Those Intel CPUs now keep the OS clock, as before the fallback. AMD CPUs still get the measured RDTSC clock (a Ryzen 7 9800X3D reports max leaf 0xd, so nothing changes there). Assisted-by: Claude Opus 5.5 (debugging, porting and drafting) Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com>
* core: detect Switch 2 programs in NSP containers (#349)cira010019 hours1-3/+22
| | | Read the selected program metadata before kernel initialization so NSP launches receive the Switch 2 memory layout and clock. This fixes Mario Kart World 1.8.0 crashing during startup while its loose 1.0 dump already boots.
* ci: build Android arm64 APKs in release-binaries (#360)Jonas19 hours1-1/+1
| | | | | Adds an android-arm64 job that builds the mainline release APK twice: as dev.eglantine.eglantine and as com.antutu.ABenchMark. The package name comes from a new appId Gradle property. Both APKs are published with the release.
* cli: exit successfully for --help and --versionShahadatTest19 hours1-0/+6
| | | | | | | | | | | | | | | ApplyLaunchParams already prints the help or version text, but SDL_AppInit then fell through to the "No ROM specified" check and returned SDL_APP_FAILURE, so `eglantine-cli --help` and `--version` logged a critical error and exited with a failure code. Return SDL_APP_SUCCESS for those two options before the ROM check. Tested: Windows and Linux CI builds; on Windows, --help and --version exit with 0 and running without a ROM still exits with a failure. AI disclosure: implemented with Claude and reviewed with Codex (AI coding assistants). (cherry picked from commit 6debe97d22)
* Merge pull request #155 from Djihads80/neo.ai/vibration-fixJonas23 hours2-6/+26
|\ | | | | Diagnoses to fix vibration support
| * Vibration support for ns2 gamesnéo Luigi24 hours2-36/+25
| | | | | | | | | | | | | | | | | | This branch supports vibration by achieving proper rumble reading from games and uses regular eglantine/eden logic from ns1 to send them over. Tested on windows 10 on Mario Kart World Assisted-by: Claude Opus 5.5 (code cleanup)
| * Merge remote-tracking branch 'origin/nx2' into neo.ai/vibration-fixnéo Luigi25 hours261-1207/+16119
| |\ | | | | | | | | | | | | | | | | | | | | | Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> # Conflicts: # src/core/hle/service/hid/hid_server.cpp # src/core/hle/service/hid/hid_server.h
| * | Vibration fix for ns2 games | Assisted by claude (code)néo Luigi3 days2-5/+36
| | |
* | | video_core: fix the -Wshadow error in the FSR 3.1 upscalerJonas24 hours1-3/+3
| | | | | | | | | | | | | | | | | | Fsr3Upscaler::Pass::Dispatch took a scheduler parameter that shadows Fsr3Upscaler::scheduler, which fails the Windows MinGW PGO build under -Werror=shadow.
* | | Merge pull request #313 from cira0100/ldn/room-handshakeMako24 hours17-286/+1047
|\ \ \
| * | | tests: cover room packet matching and size-checked ZSTD decompressioncirakg24 hours3-3/+94
| | | | | | | | | | | | | | | | Assisted-by: Claude Opus 5.5 (investigation and implementation)
| * | | network: close each bsd fd once and drop unwanted or malformed room packetscirakg24 hours8-32/+91
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Two threads closing the same fd both copied the descriptor and both called Close(), so a host socket could be closed twice, and the second closesocket could hit an unrelated socket that had reused the host fd. CloseImpl now frees the slot under file_descriptors_mutex first and only that thread closes the socket; the other gets EBADF. OnProxyPacketReceived decompressed every room packet when any fd had a socket, including native sockets and proxy sockets on other ports. Sockets now report through AcceptsProxyPacket whether they want a packet, and only those are collected, so an unwanted packet is not decompressed. DecompressDataZSTD passed the frame's declared size straight to the vector constructor, so a malformed or unsized frame from a room member threw on the room thread. The new TryDecompressDataZSTD rejects invalid, unsized and oversized frames, and bsd drops such packets with a warning. DecompressDataZSTD now returns an empty vector for them instead of throwing. Assisted-by: Claude Opus 5.5 (investigation and implementation)
| * | | Merge upstream Djihads80/Eglantine nx2 into ldn/room-handshakecirakg25 hours29-220/+1817
| |\ \ \
| * | | | tests: queue decompressed packets in the room socket testscirakg25 hours1-2/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | HandleProxyPacket now receives data that bsd has already decompressed. Assisted-by: Claude Opus 5.5 (investigation and implementation)
| * | | | network: keep fcntl modes across MSG_DONTWAIT and decompress room packets oncecirakg25 hours4-53/+65
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A receive with MSG_DONTWAIT restored the blocking mode from the descriptor copy taken before the call. When fcntl(SETFL, O_NONBLOCK) ran during the receive, the fd kept reporting O_NONBLOCK while its socket blocked again. Receives now switch the mode only for MSG_DONTWAIT and read the current flags under file_descriptors_mutex at both ends, and SETFL changes the mode and the stored flags in the same critical section. OnProxyPacketReceived decompressed each room packet once per matching socket while holding file_descriptors_mutex, so every bsd call waited for it. It now copies the distinct sockets under the lock, decompresses once without it and delivers the result. Also reject fd == MAX_FD in IsFileDescriptorValid and PollImpl, which read past the table, and guard the ProxySocket blocking and receive timeout setters with packets_mutex, matching their reader. Assisted-by: Claude Opus 5.5 (investigation and implementation)
| * | | | tests: cover room ProxySocket receives and the LDN join handshakecirakg25 hours3-0/+435
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add unit tests for the room LAN fixes in this branch. The socket tests check datagram truncation, TCP remainders and peeks, timeouts, wakeups on close and on a new packet, and stream behavior with the default protocol. The LDN tests check that a join waits for the host's reply, rejects bad or duplicate joins, ignores late replies and uses fresh identities. Assisted-by: Sol (LDN join tests) Assisted-by: Claude Opus 5.5 (room socket tests)
| * | | | network: keep bsd sockets alive across concurrent close and fix room gapscirakg25 hours3-135/+144
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | bsd runs on three host threads, but its calls kept a raw reference into the shared descriptor table while they used a socket. A close() on another thread could then destroy the socket mid-call. Waking a blocked room recv() on close made this happen every time. Every call now works on a copy of the descriptor taken under the table lock, poll() keeps its sockets alive while it waits, and close() resets the slot only if it still holds the same socket. accept() picked a free fd before blocking and only locked the write, so another thread could publish a socket in the same slot. It now picks and writes the fd in one critical section after Accept() returns. dup() now re-checks the source fd under the lock. A duplicated fd shares its socket, so the room packet loop queued each packet once per fd. Deliver it once per socket. NIFM: when the selected host adapter is missing, the room still works and IsNetworkAvailable reports it, but GetCurrentNetworkProfile returned an empty profile. Report a wired room profile in that case, and put the room address on the first adapter in EnumerateNetworkInterfaces. Assisted-by: Claude Opus 5.5 (investigation and implementation)
| * | | | Merge upstream Djihads80/Eglantine nx2 into ldn/room-handshakecirakg25 hours9-31/+56
| |\ \ \ \
| * | | | | network: use the socket type for room stream reads and wake all readerscirakg25 hours2-3/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | socket(AF_INET, SOCK_STREAM, 0) leaves the protocol unspecified, so the TCP checks in ProxySocket::Recv and ReceivePacket missed such sockets. recv() then waited for the timeout and returned EAGAIN instead of end of stream, and partial reads dropped the rest of the packet. Keep the socket type and use it for these checks. The protocol stays as it is, because it is sent to other room members. A MSG_PEEK reader leaves the packet queued, so notify every waiter when a packet arrives instead of only one. Assisted-by: Claude Opus 5.5 (investigation and implementation)
| * | | | | network: fix room socket races and share the room network checkcirakg26 hours7-56/+111
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | bsd:s, bsd:u and bsd:a share one file descriptor table, but each service bound its own proxy packet callback, so every room packet was queued three times on each socket. Bind the callback once. The room thread walked the descriptor table without a lock while bsd created and closed sockets, so it could reach a destroyed or not yet created socket. Guard the table with a mutex, and publish a socket only after it is created and initialized. Check airplane mode before an fd is taken, so a refused socket no longer leaks its slot. ProxySocket now initializes protocol, decompresses packets outside the packet lock without copying the compressed data first, and keeps a read offset for partial TCP reads instead of erasing from the front. Add Network::GetRoomIPv4Address(), set only in the Joined and Moderator states. NIFM uses it for network availability and for every reported address, including EnumerateNetworkInterfaces and GetCurrentIpAddress, so no call reports the room address while another rejects the network. Assisted-by: Claude Opus 5.5 (investigation and implementation)
| * | | | | Merge branch 'nx2' into ldn/room-handshakecirakg26 hours75-271/+2090
| |\ \ \ \ \
| * | | | | | network: fix room host LAN Play and room socket review issuescirakg26 hours2-38/+65
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The room host and room moderators are in the Moderator state, not Joined, so the airplane mode override for joined rooms did not apply to them and LAN Play still returned them to the menu. Accept both states. Share the room address override between the NIFM profile and IP config calls so they cannot drift apart. recv() on a room TCP socket now waited for the receive timeout, because Recv goes through RecvFrom. Room TCP sockets have no peer, so keep the previous immediate end-of-stream result when nothing is queued. Close() now drops queued packets and wakes a blocked recv, which then fails with EBADF. The socket state that the room thread reads when it queues a packet is now guarded by the packet mutex. Assisted-by: Claude Opus 5.5 (investigation and implementation)
| * | | | | | nifm: treat a joined room as the LAN for local network gamescirakg27 hours1-3/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | LAN Play through public lobby rooms failed in two ways. With airplane mode on (the default), IRequest::GetResult rejected the game's network request. Mario Kart World then opened the net-connect applet and returned to the main menu instead of the LAN browser. A joined room is the emulated network: its sockets only reach room members. Count it as an available network for GetResult and IsAnyInternetRequestAccepted. With airplane mode off, players could open the browser but never saw each other. Room fake IPs are spread over 192.168.0.0/16, and some room servers give members different /24s. NIFM reported the host adapter's /24 mask with the fake IP, so the games treated each other as off-subnet. Report 255.255.0.0 in a room instead. Assisted-by: Claude Opus 5.5 (investigation and implementation)
| * | | | | | network: fix ProxySocket receive edge casescirakg27 hours2-51/+36
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Routing recv() through RecvFrom made several old RecvFrom problems reachable from the normal read path: - A partial TCP read kept zero bytes in front of the unread data. - A blocking read busy-waited with yield() and reported ETIMEDOUT. - MSG_PEEK hit the flags == 0 assert. - A UDP datagram larger than the buffer was dropped with EMSGSIZE. Wait on a condition variable signalled when a packet arrives, and report an expired wait as EAGAIN like an SO_RCVTIMEO timeout. Keep the existing 5s cap for sockets without a receive timeout. Allow MSG_PEEK. Truncate oversized datagrams as BSD recv() does, and keep the unread tail of a TCP packet for the next read. Assisted-by: Claude Opus 5.5 (investigation and implementation)
| * | | | | | network: deliver room datagrams through ProxySocket::Recvcirakg27 hours1-5/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When connected to an emulator room every guest socket is a ProxySocket. Its Recv was a stub that always returned zero bytes, so games that read UDP replies with recv() never received them. Mario Kart World LAN Play reads its discovery replies this way, so guests never saw the host's room in the LAN browser. Delegate Recv to RecvFrom without an address, so queued room packets, non-blocking, timeout, peek and truncation behaviour match recvfrom(). Assisted-by: Claude Opus 5.5 (investigation and implementation)
| * | | | | | Merge branch 'nx2' into ldn/room-handshakecirakg27 hours22-71/+1299
| |\ \ \ \ \ \
| * | | | | | | ldn: wait for the host's reply when joining a networkcirakg33 hours3-15/+89
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Connect slept for a second while holding packet_mutex, so the host's SyncNetwork reply could not be handled until Connect had already returned success in StationOpened. Players could see each other's group and enter it, but never actually met. Wait on a condition variable instead, accept the reply only from the selected host and session, and fail after five seconds. Check packet sizes and senders, stop duplicate joins from taking another station, and seed session IDs so separate networks don't share one. The SDL frontend never called Network::Init, so its multiplayer option could not join a room. Initialize and shut down networking around the core. Assisted-by: Sol (implementation) Assisted-by: Claude Opus 5.5 (code review)
* | | | | | | | fix: update BUILD_ID definition and improve path handling in GameListWorkerkraibse25 hours2-1/+3
| | | | | | | |
* | | | | | | | nx2: improve save data handling for titles with missing NACP sizes to ↵kraibse25 hours1-20/+16
| |_|_|_|/ / / |/| | | | | | | | | | | | | | | | | | | | redirect the user to the correct save location
* | | | | | | nup_writer: keep the dump's own layout for non-exefs/romfs entriesa55uka25 hours1-2/+5
| | | | | | |
* | | | | | | Merge pull request #346 from Duck912/fe-fsr31nowhere0225 hours22-181/+1559
|\ \ \ \ \ \ \ | | | | | | | | | | | | | | | | FSR 3.1 implementation for DLSS games
| * \ \ \ \ \ \ Merge remote-tracking branch 'origin/nx2' into fe-fsr31Duck91225 hours81-289/+2166
| |\ \ \ \ \ \ \ | | | |_|_|_|_|/ | | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | # Conflicts: # src/video_core/renderer_vulkan/blit_image.cpp # src/video_core/renderer_vulkan/blit_image.h
| * | | | | | | video_core: replace Fortune's Weave's DLSS with AMD FSR 3.1Duck91227 hours18-34/+1119
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fire Emblem: Fortune's Weave's DLSS network can't run here, and the temporal stand-in is only an approximation of it. FSR 3.1 takes the same inputs DLSS does: the jittered colour, motion vectors, the jitter and the depth, which the game's first DLSS pass reads through cbuf0+0x298 (Z32, reversed, the colour's size). Kepler compute keeps it next to the motion vectors. Fsr3Upscaler ports the host side of the SDK's ffx_fsr3upscaler.cpp: the eight passes (prepare inputs, luma and shading-change pyramids, shading change, reactivity, luma instability, accumulate, RCAS), the internal images and the constants, recorded through the scheduler with the shaders from externals/FidelityFX-SDK. It takes HDR colour, render-size motion vectors and reversed depth, computes its own exposure, and uses the no-wave SPD variants on devices without compute quad operations. The SDK's GLSL uses separate textures and samplers, so DescriptorBankInfo gains sampled image and sampler counts (default 0). FSR's RCAS follows the RCAS Sharpness slider. The result goes to FSR's own RGBA16F image and is drawn into the game's output, which keeps its format. TextureCacheRuntime::TemporalUpscale runs FSR 3.1 first. Without the depth, at mismatched scales, on a device lacking FSR's formats or features, or if its pipelines fail to build, the stand-in runs instead, and the bilinear blit stays last. EDEN_NX2_DLSS_REPLACEMENT=standin forces the stand-in. A gap of more than 250 ms between evaluations restarts the history. The BlitColor overload that takes a raw image view transitions its source to SHADER_READ_ONLY_OPTIMAL but described it as GENERAL in the descriptor (a validation error); it now describes the layout it uses. Assisted-by: Claude Opus 5.5 (debugging, implementation and drafting) Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com>
| * | | | | | | video_core: sharpen the temporal DLSS stand-inDuck91227 hours9-147/+440
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fire Emblem: Fortune's Weave's DLSS input matches Eden's (same 720p image, same detail), but the stand-in's 1440p output was blurrier than a plain bilinear 2x of it (Laplacian 0.0066 vs 0.0081; Eden's real DLSS 0.0111), and the image drifted darker over time: - the sample kernel was about twice too wide for the output resolution; - the history was kept in the output's B10G11R11 format, whose 5-6 bit mantissas round away a frame's 0.03-0.1 share; - the 1-sigma neighbourhood clip removed detail that only some jitter positions sample (railings, thin edges). The history is now an RGBA16F pair the shader writes as a storage image, with no per-frame copy. Still pixels use a third of the kernel width and a 1.5-sigma clip, so detail from many jitter positions accumulates. Moving pixels keep the old kernel and 1-sigma clip, and so do pixels that moved recently or whose history falls far outside the neighbourhood (content that changes without motion vectors), remembered in the history's alpha. Static output goes from 0.0066 to 0.0102 with no brightness drift and no new ghosting. With resolution scaling the stand-in used to fall back to a bilinear blit. The images are now scaled up as BlitImage does, the jitter is scaled to host pixels and the history follows the framebuffer's render area. RCAS (temporal_sharpen.frag) sharpens a copy of each result, never the history, in range-compressed space since the output is HDR. Its strength is the sharpness slider, relabelled "RCAS Sharpness" (0% turns it off). EDEN_NX2_TEMPORAL_KERNEL, _CLIP, _KERNEL_MOTION, _CLIP_MOTION and _WEIGHT tune the filter (all four filter values at 1 give the old one), and EDEN_NX2_TEMPORAL_SHARPEN=<stops>|off overrides the slider. Assisted-by: Claude Opus 5.5 (debugging, implementation and drafting) Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com>
| * | | | | | | qt_common: name the FSR filter and frame generation entries by what they doDuck91227 hours2-6/+6
| | |_|/ / / / | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The window filter "AMD FidelityFX Super Resolution 3" (present/fsr3.cpp) runs FSR 1's EASU and RCAS with RCAS at 0.8x the slider and no temporal blending, and the frame generation type "FSR 3" (present/fsr3_frame_gen.cpp) is Eglantine's own optical-flow interpolation, not AMD's. Both names suggested AMD's FSR 3 upscaler. Label them "AMD FidelityFX Super Resolution 1, softer sharpening" (FSR 1 Soft) and "Optical Flow Interpolation (built-in)" (Optical Flow), and the plain FSR filter "AMD FidelityFX Super Resolution 1 (FSR 1)". Only the display text changes; setting ids and enum values stay, so configs carry over. Assisted-by: Claude Opus 5.5 (investigation and drafting) Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com>
* | | | | | | nx2: video decoder: copy NV12 frames from a GPU decoder without swscaleJonas25 hours1-0/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | FFmpeg 6.1's swscale leaves the chroma plane of an NV12 to NV12 copy at zero, so movies decoded on the host GPU (Mario Kart World's pre-race movie, Hyrule Warriors' cutscenes) showed green. CPU-decoded frames (YUV420P) were not affected.
* | | | | | | nx2: video decoder: keep post-stream release fences pendingJavier25 hours1-2/+39
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Bananza's movie player acquires one decoded frame every time a released output image's fence completes, and aborts (2111-3604) when the ring is empty. Completing those fences at once after the end of a stream (the Mario Kart World workaround) made it acquire from an empty ring the moment its cutscene movies ended. Released images now keep their normal pending fence after the end of a stream. Stop (207) and Finalize (115) complete every fence handed out so far, so a client that waits on its returned images after a movie is still released when it stops the decoder. EDEN_NX2_VDEC_EOS_RELEASE_NOW=1 restores the old immediate completion; EDEN_NX2_VDEC_TRACE=1 logs every decoder call. Tested on Bananza: the post-breakout cutscene movie ends and gameplay continues (mining tunnel). Mario Kart World not retested. Assisted-by: Claude (Anthropic) for investigation and code. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit 0f8eaa54be5bff351de7c9a80cc06a4b3453bc76) (cherry picked from commit 8ed051843a33a5dec086d1ec6985798c8b336a6a)
* | | | | | | nx2: vdecsvc refreshes the GPU copy of each decoded frame (Yoshi demo)rdenno25 hours1-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 144b193c841a4b291e5eca065c94cbe82136a4b1)