| Commit message (Collapse) | Author | Age | Files | Lines |
| ... | |
| | | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
The Switch 2 SDK filters its class enumeration by flags bits 40..43 (2D,
3D, compute and inline-to-memory) before it picks its context classes.
Without them Fire Emblem: Fortune's Weave tears NVN down at boot
(2162-0001). Bisected against the Eden NS2 tree's characteristics block;
its other differences are not needed.
Assisted-by: Claude Opus 5.5 (bisecting and drafting)
Signed-off-by: duck912 <350528965+Duck912@users.noreply.github.com>
|
| | | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
The Switch 2 SDK asks for the {gpc, tpc} pair of every virtual SM and
treats a pair left at its 0xc0c0 sentinel as failure; with the ioctl
unimplemented, Fire Emblem: Fortune's Weave tore NVN down at boot
(2162-0001). Fill every pair: one GPC, two SMs per TPC.
Assisted-by: Claude Opus 5.5 (debugging, porting and drafting)
Signed-off-by: duck912 <350528965+Duck912@users.noreply.github.com>
|
| | | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
Fire Emblem: Fortune's Weave creates a graphics device with gpu 41 and
uses the returned id in later NvRm calls; auto-stubbed, it got id 0 and
NVN setup failed. Hand out ids from 1 and free them with 42.
gpu 202 answered (0, 0) for an empty partition, which the SDK reads as a
one-byte partition at address 0. An empty one is min ~0, max 0.
Assisted-by: Claude Opus 5.5 (debugging, porting and drafting)
Signed-off-by: duck912 <350528965+Duck912@users.noreply.github.com>
|
| | | | | | | |
|
| | |\ \ \ \ \ |
|
| | | |/ / / /
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
Mario Kart World has a compute shader with HSETP2.EQ.AND P0, PT,
R44.H0_H0, R44.H1_H1, P0 (opcode 0x234), which only had the immediate
form (0x434) and so rejected the whole program. Lower it to Maxwell
HSETP2 (reg) the same way, with the B register, swizzle, abs and neg
in bits 20-31.
|
| | | | | | | |
|
| | | | | | |
| | | | | |
| | | | | |
| | | | | | |
(add IsGpuWrittenCommands method to check GPU-written entries)
|
| | | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
The collector's usage leaves out the unused part of VMA's blocks, but
the driver counts it and a heap at its budget cannot give it to a new
image. On an RX 7800 XT that slack was 1.06 GiB, the whole 1 GiB margin:
the heap sat at its budget for a minute while the collector saw room,
then images stopped fitting and the process died. Reserve the slack
(capped at 1.5 GiB) on top of the margin: at once when it grows, slowly
when it shrinks, so eviction leaving partly used blocks doesn't chase
the threshold down.
Assisted-by: Claude Sonnet 5.5 (diagnosis and code)
(cherry picked from commit 73fd5a489ea28226fa16a55f5008e622d631b54c)
|
| | | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
Three pixel shaders were rejected, skipping their draws (fog missing).
TXD refused word 2 bit 90, which its own emit already forwards as
NODEP; TXQ refused mask 4 (depth), whose Maxwell mask bit is passed
through as for the other masks.
(cherry picked from commit a42b4d4c744e12ce5262648eee50daecd1ca4681)
|
| | | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
GameChat polls nx2:camera command 29 every frame; it was logged as an
unimplemented function (Critical plus Warning), 40,000 times in one
session. Answer 3, 21 and 29 with the same empty success, logging each
once.
Assisted-by: Claude Sonnet 5.5 (code)
(cherry picked from commit 0b7b562898bba137934420b366e3980476ee221f)
|
| | | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
When VRAM ran out, any image that failed to allocate became a sparse
image with nothing bound, which AMD's drivers don't survive being
sampled (an RX 6600 died mid-flood, an RX 7800 XT made 211 of them,
8x8 ones included). Try host memory first, and count the images that
didn't fit: the texture cache then keeps more room under the budget
(512 MiB a step, up to 3 GiB, decaying) so its collector runs earlier.
The sparse fallback stays for images too large to back.
|
| | | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
Native programs were captured and lowered when their ShaderInfo was
made and again for every environment built for their pipelines. The
ShaderInfo now keeps the lowered code and the environments adopt it.
Capture also reads a 4 KiB page at a time instead of flushing caches per
instruction, and cached native programs fold bank 1 reads like live ones.
Ported from Wael3rd/Eglantine-MKW (0ae093058e, 65a6aa877a, df076133c4).
Assisted-by: Claude Sonnet 5.5 (porting the fixes)
(cherry picked from commit 3af11ac401ad3061c183281d8c98c16c1d6da456)
|
| | | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
With the present waiting for the previous frame's fence, the game
refills command memory it already submitted while the GPU thread is
still running that frame, so some frames rendered into the wrong image.
Copy each entry's words at submit and execute the copy. Resumed entries
and ranges the GPU has newer words for still read memory.
EDEN_NX2_PB_SNAPSHOT=0 executes from memory.
Ported from Wael3rd/Eglantine-MKW (bd3119a86f).
Assisted-by: Claude Sonnet 5.5 (porting the fix)
(cherry picked from commit 408bb84d06ae0729697ef9bed2c2ba76ce6dff42)
|
| | | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
Image::InitSparseLayers divided by the imageGranularity the driver
returns, which AMD's driver reports as 0 and crashed. Use Vulkan's
standard 2D block shape when the device reports
residencyStandard2DBlockShape, otherwise don't use sparse layers.
Ported from Wael3rd/Eglantine-MKW (7a77946af3).
Assisted-by: Claude Sonnet 5.5 (porting the fix)
(cherry picked from commit eadb9fc0f06f32ff1684fe202519c0505669095d)
|
| | |\| | | |
| | | | | |
| | | | | | |
bring nx2-experimental up to date
|
| | | |/ / / |
|
| | |\ \ \ \
| | | | | |
| | | | | |
| | | | | | |
test/linux-all-prs-plus
|
| | | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
BuildHandleProgram stored the address of its outermost call's local map
in a thread_local pointer for the nested calls, which GCC 15 rejects
with -Werror=dangling-pointer. The map itself is thread_local now, and
a depth counter tells the outermost call to clear it.
|
| | | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
Deleting by age alone left every block partly used: the collector deletes
thousands of images a minute and new ones land in the holes, so blocks
seldom empty (title 1: ~0.8 GB of holes in ~190 32 MiB blocks after ten
minutes, counted by the driver as used). Among the oldest candidates, 8
per image a pass may delete, those in the emptiest blocks go first, so
blocks drain and VMA returns them; placement already prefers the fullest
blocks.
(cherry picked from commit 2f8f0716fafd874cfbb3cc9086141aea61aff2df)
|
| | | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
Images whose guest memory is not contiguous were left out of the cold
hint. With sparse tile remaps Mario Kart World maps its own memory into
such images, and its game memory in RAM rose by ~1.9 GB in one run. Each
mapped piece is now hinted.
(cherry picked from commit 97f034615c174178301a4999c334fb39cd03e568)
|
| | | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
Title 1 clears about 1 GB of its sparse regions at boot through the GPU
memory manager. Every block the clear touched got 4 MiB of guest memory,
which the clear itself then committed on the host, and counted as written,
so the texture cache gave the images over it device memory too. A block
nobody wrote reads zero already: when the part of a write that lands on
it is all zero, leave it as it is.
(cherry picked from commit 0d7ff63fd1a373cecff6ba91022c9027e801e53f)
|
| | |\ \ \ \ \
| | | | | | |
| | | | | | |
| | | | | | | |
test/linux-all-prs-plus
|
| | | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | | |
A trimmed ASTC array kept up to 512 MiB on the host. On GPUs with less
than 7 GiB it now keeps up to 256 MiB (one mip level less): Mario Kart
World's two terrain arrays took 724 MiB of a 6 GB card next to ~1.2 GB
of other sparse terrain textures. EDEN_NX2_ASTC_ARRAY_MIB=<MiB> sets the
limit.
|
| | |\ \ \ \ \ \
| | | | | | | |
| | | | | | | |
| | | | | | | | |
test/linux-all-prs-plus
|
| | | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | | |
A draw of N instances arrives as Begin(First)/End and N-1 Begin(Subsequent)/
End pairs. The draw manager draws the first at once and the rest together at
DrawDeferred, which ran at the next Begin(First) or when the macro returned.
NVN's draw macros reset the base instance register and its copy in
c[0][0x644] right after the loop, before returning, so the deferred instances
were drawn with base instance 0 and read the first records of the instance
buffer instead of their own.
In Mario Kart World every tree mesh is drawn this way, from one shared
instance buffer: each mesh got other meshes' transforms, which showed as
low-detail, inflated or scattered trees.
Any write other than the loop's own methods (draw begin/end, vertex and
index counts, inline indices) now draws the waiting instances first.
|
| | |\ \ \ \ \ \ \
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | | |
test/linux-all-prs-plus
# Conflicts:
# src/core/hle/service/service.cpp
|
| | | | |/ / / / /
| | |/| | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | | |
Every call to an auto-stubbed command wrote a Critical report, and
Critical flushes the log file. Mario Kart World polls nx2:camera 29 about
47 times a second, so the log flushed that often for the whole session.
Each (service, command) pair is reported once; repeats answer success
silently.
|
| | |\ \ \ \ \ \ \
| | | | | | | | |
| | | | | | | | |
| | | | | | | | | |
test/linux-all-prs-plus
|
| | | |/ / / / / /
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | | |
A missing prod.keys raised a Yes/No question in the main window's
constructor, and every launch (also -g launches from scripts) waited on
it. Loose ExeFS/RomFS dumps, all Switch 2 games so far, need no keys.
Startup now only logs a warning; installing firmware or keys still asks.
|
| | |\ \ \ \ \ \ \
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | | |
test/linux-all-prs-plus
# Conflicts:
# src/core/hle/service/nvdrv/nvdrv.cpp
|
| | | | |/ / / / /
| | |/| | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | | |
Mario Kart World runs small command lists (20-byte entries) that its
culling dispatches fill in each frame. Accurate GPU mode reads every
command list through the caches; Fast mode reads guest memory directly
(on the split's front thread too), where those entries were still the
words of an older frame, so the draws behind them were left out: the
trees around the courses vanished in Fast mode only.
The buffer cache now also marks the device pages the GPU writes (shader
stores, copies of GPU-written data) in a bitmap the split's front can
read. A command list on such a page waits for the back to run what was
queued before it and is flushed when its words are still only in host
buffers. In a race that is ~5% of command lists (13,500 a second of
262,000) and ~400 flushes a second.
|
| | |\ \ \ \ \ \ \
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | | |
test/linux-all-prs-plus
# Conflicts:
# src/common/host_memory.h
|
| | | | |/ / / / /
| | |/| | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | | |
The kernel clears every page it hands out, and the backing memory is a
page-file section the host only gives RAM to once a page is touched. So
the clears themselves made every page of a game's heap resident: Mario
Kart World (12 GB layout) had a 12.5 GB working set 20 s after boot.
HostMemory keeps two bits per 64 KiB of backing: used (handed out by the
kernel at least once) and dirty (may hold data). Pages returned to the
kernel mark their granules dirty, and a zero clear only touches dirty
granules; a granule cleared in full is clean again. A new kernel on the
same memory marks everything a previous one used dirty, so leaked
processes can't leak data into the next game. KMemoryManager's
optimized-process fill and KSharedMemory's clear go through the same
path.
Mario Kart World, title screen and attract demo, 180 s: working set 20 s
in 4.7-6.4 GB instead of 12.5 GB, peak 14-17.6 GB instead of 20.1 GB.
|
| | |\ \ \ \ \ \ \
| | | | | | | | |
| | | | | | | | |
| | | | | | | | | |
test/linux-all-prs-plus
|
| | | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | | |
Compiling a block is most of what makes Mario Kart World stutter in its
first minute: the game's thread translates ~20,000 blocks in a few
hundred milliseconds when a scene loads, and the frame waits. A CPU
profile of those bursts had ~40% of the compile time in two loops over
all 96 host locations (16 GPRs, 16 XMMs, 64 spill slots) per IR
instruction:
- EndOfAllocScope called ReleaseAll on every location, though an
instruction touches a few. It now skips the ones ReleaseAll would not
change (no references or locks, not scratch, no last use pending, and
values either still live or fully cleared).
- DefineValueImpl checked, with an assert that stays on in release
builds, that the defined value was in no location yet, and afterwards
that it was where it was put. Those scans are DEBUG_ASSERTs now.
Mario Kart World, first 45 s (boot, world map, title, attract demo):
18.5 -> 12.8 us per compiled block; frames over 60 ms 57 -> 31, over
100 ms in the first 600 presents 23 -> 12; frames render as before.
|
| | |\ \ \ \ \ \ \ \
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | | |
test/linux-all-prs-plus
|
| | | |/ / / / / / /
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | | |
Each emulated core has its own JIT, and Mario Kart World runs six. After
three minutes of its title screen and attract demo, their bookkeeping
held ~1.65 GB besides ~470 MB of compiled code, mostly empty slots:
- patch_information: four small_vectors of code pointers per linked
block (232 bytes a slot), and Patch() added an entry for every block
compiled, linked or not (~800 MB);
- block_ranges: an interval map with a hash set per segment (~300 bytes
a block, ~460 MB) to answer invalidations, which only come when code
is unmapped or reprotected;
- fastmem_patch_info: 48 bytes per fastmem access in a hash map
(~340 MB).
Patch locations are now offsets into the code space with the patch kind
in the low two bits, two inline and the rest in a vector, and Patch()
no longer creates entries. Block ranges are a flat list scanned on
invalidation (also dropping the invalidated blocks' ranges, the old
TODO). Fastmem patch information is a list sorted by code offset (code
is emitted in address order, so inserts are appends) with 24-byte
entries, looked up by binary search when an access faults.
Mario Kart World, 180 s: resident private memory at 150 s 6195 ->
4777 MiB, peak commit 16.0 -> 14.4 GB; frames and frame times unchanged.
|
| | |\ \ \ \ \ \ \ \
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | | |
test/linux-all-prs
|
| | | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | | |
vi2 229 carries the size the game drew into the presented image in word
7, ((height - 1) << 16) | (width - 1), from the image's top-left corner:
Kirby Air Riders draws 1920x1080 into 2560x1440 images (0x0437077f) and
Mario Kart World 2560x1440 into 3840x2160 ones (0x059f09ff). Docked,
Kirby's frame sat in the top-left corner with black to the right and
below. Crop to the given size; the handheld 1920x1080 limit still
applies, and Mario Kart World's docked crop stays only for presents that
give none.
|
| | |\ \ \ \ \ \ \ \ \
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | | |
test/linux-all-prs
# Conflicts:
# src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
|
| | | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | | |
Without vulkan_used.bin (the first boot with this change, or a session
that ended before saving it) every cached graphics pipeline was still
built at boot. A Linux tester's cache had grown to 47,951 pipelines over
many builds: ~21 GB of driver memory built before the game started,
filling RAM and swap. The list is only saved at exit or after two
minutes, so a boot that ran out of memory never saved one and the next
boot did the same.
Build at most 3,000 cached graphics pipelines at boot in that case and
the rest when first needed; the next session uses the saved list.
EDEN_NX2_PRELOAD_ALL_PIPELINES=1 still builds all of them.
|
| | | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | | |
Each built pipeline holds ~0.45 MB of driver memory and none was ever
destroyed, so it grew with every place a session went. One unused for
9000 frames is destroyed once the GPU is past it and built again from
the driver's pipeline cache (2-3 ms) if it is needed later; the
transitions between pipelines are cleared, and pipelines used this
session still go to the used list. Mario Kart World's title screen, 10
minutes: 1,714 evicted, 1,700-1,850 kept instead of a count that only
grows.
(cherry picked from commit 24a37800034f83ec1d8fe9e8e5642d27eb2935b8)
|
| | | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | | |
Each pipeline built at boot holds ~0.45 MB of driver memory. Mario Kart
World built 4,789 from the eight sessions the list kept, while one
session of its title screen uses ~1,500. With the last two sessions it
built 1,035 at boot and 972 when first needed: the emulator's own memory
at five minutes 6.4 -> 5.6 GB, frames over 100 ms 9 -> 10 (none built at
boot: 4.9 GB, but 38 frames over 100 ms). Lists saved with the longer
window are trimmed when they are loaded.
|
| | | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | |
| | | | | | | | | | | |
Every graphics pipeline in the disk cache was built at boot, and each one
holds driver memory: Mario Kart World builds 6.5k (the NVIDIA driver keeps
~1.6 GB for them) and a session uses about a quarter. Record the pipelines
each session uses in <title>/vulkan_used.bin (key hash + sessions since the
last use, dropped after 8), build only those at boot and the rest when a
game first needs them, without storing them in the disk cache again. The
first session without the file builds everything as before.
EDEN_NX2_PRELOAD_ALL_PIPELINES=1 keeps building all of them.
|
| | |\ \ \ \ \ \ \ \ \ \
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | | |
into test/linux-all-prs
|
| | | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | | |
The RGBA8 image an ASTC texture is decoded into before BC1/BC3
compression was made for each texture (263 us) and freed once the GPU
was past it. Once the GPU is done with one it now decodes the next
texture of the same shape: title 1's title screen decodes dozens of
textures a frame, mostly of a few shapes. Free ones are kept up to
256 MiB and destroyed after 60 unused frames.
Taking them from VMA's shared blocks instead was faster (90 us), but
freeing dozens a frame there left ~1 GB of those blocks unused. Against
that, Mario Kart World's title screen over 10 minutes: VRAM in use 6.34
-> 5.90 GB on average, peak 6.99 -> 6.45 GB.
|
| | |\ \ \ \ \ \ \ \ \ \ \
| | | | | | | | | | | | |
| | | | | | | | | | | | |
| | | | | | | | | | | | | |
test/linux-all-prs
|
| | | |/ / / / / / / / / /
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | | |
256 MiB sat mostly unused in device memory on Switch 2 titles. FreeBSD
already used 128 MiB.
|
| | |\ \ \ \ \ \ \ \ \ \ \
| | | | | | | | | | | | |
| | | | | | | | | | | | |
| | | | | | | | | | | | | |
test/linux-all-prs
|