Merge main: its fix for the see-through ground with its finalize counters, which take the place of the counter of this line, and the AppImage runner fixes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
epicmeme546
2026-11-11 12:55:32 -05:00
2 changed files with 48 additions and 9 deletions

View File

@@ -35,7 +35,29 @@ jobs:
- uses: astral-sh/setup-uv@v6
- name: Shader compilers
# make_appimage.py compiles the runtime's own shaders (tools/build_shaders.py: glslc, spirv-as, spirv-val)
run: sudo apt-get update && sudo apt-get install -y glslc spirv-tools
# On 2026-11-11 the runners could not resolve Ubuntu's archive hosts (azure.archive.ubuntu.com, then
# archive.ubuntu.com) and apt failed every fetch for hours. When they do not resolve, the three tools come from
# LunarG's Vulkan SDK for Linux instead, which holds all of them.
run: |
if getent hosts azure.archive.ubuntu.com >/dev/null || getent hosts archive.ubuntu.com >/dev/null; then
sudo apt-get update && sudo apt-get install -y glslc spirv-tools && exit 0
echo "::warning::apt failed: the shader compilers come from the Vulkan SDK"
else
echo "::warning::Ubuntu's archive does not resolve: the shader compilers come from the Vulkan SDK"
fi
sdk="$RUNNER_TEMP/vulkan-sdk"
mkdir -p "$sdk"
for f in vulkan-sdk.tar.xz vulkan-sdk.tar.gz; do
curl -fsSL --retry 3 -o "$RUNNER_TEMP/$f" "https://sdk.lunarg.com/sdk/download/latest/linux/$f" &&
tar -xf "$RUNNER_TEMP/$f" -C "$sdk" && break
done
bin=$(dirname "$(find "$sdk" -type f -name glslc -path '*/bin/*' | head -1)")
test -x "$bin/glslc" && test -x "$bin/spirv-as" && test -x "$bin/spirv-val"
echo "$bin" >> "$GITHUB_PATH"
if ! "$bin/spirv-as" --version >/dev/null 2>&1; then # the SDK's tools may link its own shared libraries
echo "LD_LIBRARY_PATH=$(cd "$bin/../lib" && pwd)${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" >> "$GITHUB_ENV"
fi
"$bin/glslc" --version | head -1
- name: Shader translator and VMA
run: |
uv venv -q --python 3.12 .venv

View File

@@ -1537,6 +1537,15 @@ int vk_texture_pool_fresh_locked(void) {
// slot_resolve's last answer was none because of its stale rule (vk_texture_slot_retry_locked)
static int resolve_stale;
// NX2NAVI_TRACE=perf, since the last perf line: slots a finalize marked (its own texture object's), slots at the storage
// with the same parameters registered with another texture object, which a finalize leaves current
// (vk_texture_release), and lookups the stale rule answered with the stand-in (slot_resolve). _hm: of them, the
// terrain's streamed heightmaps (R32F 260x260), whose stand-in draws a chunk of ground at height zero.
static uint64_t n_fin_own, n_fin_other, n_fin_other_hm, n_stale, n_stale_hm;
static int terrain_heightmap(const tex_t *t) {
return t->d.format == NVN_FORMAT_R32F && t->d.width == 260 && t->d.height == 260;
}
int vk_texture_slot_retry_locked(int id) {
if (id < 0 || id >= ntslots || !tslots[id].used || !tslots[id].t.mem) return -1;
resolve_stale = 0;
@@ -2354,7 +2363,6 @@ static void slots_text(char *out, size_t n, const Tex *e) {
// undefined image, which nothing else reports. One line per entry and up to MARK_LINES per address (said_at); the
// marked slots that met such an entry are counted in the texture origins line whether or not a line was written.
static uint64_t n_mark_empty, n_mark_none; // since the last perf line: marked slots that met such an entry; that show none
static uint64_t n_fin_other; // since the last perf line: slots a finalize left current, registered by another texture there
#define MARK_LINES 6
#define MARK_LINES_ALL 20000
static void marks_check(Tex *e, uint32_t id, uint64_t now, int followed) {
@@ -3573,8 +3581,12 @@ void vk_texture_release(const tex_t *t) {
TexKey sk;
make_key(&s->t, &sk);
if (memcmp(&sk, &k, sizeof k)) continue;
if (s->t.serial != t->serial) n_fin_other++;
else s->finalized = 1, s->ce = NULL, changed = 1;
if (s->t.serial != t->serial) { // another texture object's registration: it stays current
n_fin_other++, n_fin_other_hm += terrain_heightmap(&s->t);
continue;
}
s->finalized = 1, s->ce = NULL, changed = 1;
n_fin_own++;
}
if (e && !e->released) {
mark_released(e);
@@ -3723,7 +3735,7 @@ static Tex *slot_resolve(TexSlot *s, view_t *view, int *has_view) {
// after its released image was evicted; registering the descriptor again makes it current.
if (!e && any) e = any;
else if (!e && !cpu_slot) e = own && own->superseded ? NULL : own; // a superseded one: entry_of takes it back
else if (!e && cpu_slot && s->finalized) stale = 1;
else if (!e && cpu_slot && s->finalized) stale = 1, n_stale++, n_stale_hm += terrain_heightmap(&s->t);
}
resolve_stale = stale;
if (!e && s->t.mem && !stale) {
@@ -3973,13 +3985,18 @@ void vk_texture_new_submit(void) {
rt_log("perf: frame %llu: texture origins: released entries dropped past RELEASED_MAX %llu, replaced by another "
"descriptor at their address %llu; entries the CPU does not write made without content at an address it "
"can see: on their own %llu, over a released entry %llu, over a live one %llu; marked slots that met an "
"entry without content %llu, that show no entry %llu; slots a finalize left current, registered by another texture "
"of the same parameters at its storage (a streamed terrain heightmap) %llu",
"entry without content %llu, that show no entry %llu",
(unsigned long long)f * 60, (unsigned long long)n_drop_by[DROP_MAX], (unsigned long long)n_drop_by[DROP_REPLACED],
(unsigned long long)n_cpu_empty[0], (unsigned long long)n_cpu_empty[1], (unsigned long long)n_cpu_empty[2],
(unsigned long long)n_mark_empty, (unsigned long long)n_mark_none, (unsigned long long)n_fin_other);
(unsigned long long)n_mark_empty, (unsigned long long)n_mark_none);
memset(n_drop_by, 0, sizeof n_drop_by), memset(n_cpu_empty, 0, sizeof n_cpu_empty);
n_mark_empty = n_mark_none = n_fin_other = 0;
n_mark_empty = n_mark_none = 0;
rt_log("perf: frame %llu: texture finalizes: slots marked %llu; slots of another live texture with the same "
"parameters at the storage, left current %llu (terrain heightmaps %llu); lookups the stale rule gave the "
"stand-in %llu (terrain heightmaps %llu)", (unsigned long long)f * 60, (unsigned long long)n_fin_own,
(unsigned long long)n_fin_other, (unsigned long long)n_fin_other_hm, (unsigned long long)n_stale,
(unsigned long long)n_stale_hm);
n_fin_own = n_fin_other = n_fin_other_hm = n_stale = n_stale_hm = 0;
if (split_mode > 0)
rt_log("perf: frame %llu: split fill: entries the CPU does not write started with their storage's bytes: "
"copied from the released entry they replaced %llu, filled from storage %llu (%.1f MiB, %.2f ms), "