Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions dm/gfx/nvn/hle_nvn.c
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,13 @@ NVN(nvnSamplerBuilderGetWrapMode, void, const NVNsamplerBuilder *b, NVNwrapMode
NVN(nvnSamplerBuilderGetLodClamp, void, const NVNsamplerBuilder *b, float *lo, float *hi) { // Bayonetta 3 reads it back while building its samplers
const samp_par *o = &((const samp_builder_t *)b)->p; *lo = o->lod_min; *hi = o->lod_max;
}
NVN(nvnSamplerBuilderGetLodBias, float, const NVNsamplerBuilder *b) { return ((const samp_builder_t *)b)->p.lod_bias; }
NVN(nvnSamplerBuilderGetCompare, void, const NVNsamplerBuilder *b, NVNcompareMode *mode, NVNcompareFunc *func) {
const samp_par *o = &((const samp_builder_t *)b)->p; *mode = (NVNcompareMode)o->cmp_mode; *func = (NVNcompareFunc)o->cmp_func;
}
NVN(nvnSamplerBuilderGetBorderColor, void, const NVNsamplerBuilder *b, float *c) { memcpy(c, ((const samp_builder_t *)b)->p.border, 16); }
NVN(nvnSamplerBuilderGetMaxAnisotropy, float, const NVNsamplerBuilder *b) { return ((const samp_builder_t *)b)->p.aniso; }
NVN(nvnSamplerBuilderGetReductionFilter, NVNsamplerReduction, const NVNsamplerBuilder *b) { return (NVNsamplerReduction)((const samp_builder_t *)b)->p.reduction; }
NVN(nvnSamplerInitialize, NVNboolean, NVNsampler *s, const NVNsamplerBuilder *b) {
samp_t *o = (samp_t *)s; memset(o, 0, sizeof *o); o->magic = MAGIC('S', 'M', 'P', 0); o->p = ((const samp_builder_t *)b)->p; return 1; // nvn_obj.h samp_t: games hash the bytes
}
Expand Down
30 changes: 30 additions & 0 deletions dm/gfx/tests/t_nvn.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,36 @@ int main(void) {
EXPECT("NVN2: the memory pool page size is read at run time", DEVINFO_RT, g_devinfo2[NVN_DEVICE_INFO_MEMORY_POOL_PAGE_SIZE]);
EXPECT("NVN2: items up to 0xA9", 0xAA, (int)(sizeof g_devinfo2 / sizeof *g_devinfo2));

{ // #872: renderer setup reads its builder back through the exported NVN ABI.
NVNsamplerBuilder builders[2] = {0};
for (int i = 0; i < 2; i++) P(nvnSamplerBuilderSetDefaults)(&builders[i]);
const float border[4] = {-0.25f, 0.5f, 0.75f, 1.f};
P(nvnSamplerBuilderSetLodBias)(&builders[0], -2.25f);
P(nvnSamplerBuilderSetCompare)(&builders[0], NVN_COMPARE_MODE_COMPARE_R_TO_TEXTURE, NVN_COMPARE_FUNC_GEQUAL);
P(nvnSamplerBuilderSetBorderColor)(&builders[0], border);
P(nvnSamplerBuilderSetMaxAnisotropy)(&builders[0], 8.f);
P(nvnSamplerBuilderSetReductionFilter)(&builders[0], NVN_SAMPLER_REDUCTION_MAX);
// Query a changed builder, an independent default builder, then the
// changed one after SetDefaults. Expected values do not read host state.
for (int i = 0; i < 3; i++) {
if (i == 2) P(nvnSamplerBuilderSetDefaults)(&builders[0]);
const NVNsamplerBuilder *b = &builders[i == 1];
NVNcompareMode mode = NVN_COMPARE_MODE_LARGE;
NVNcompareFunc func = NVN_COMPARE_FUNC_LARGE;
float color[6] = {13.f, 17.f, 19.f, 23.f, 29.f, 31.f};
const float want[6] = {13.f, i ? 0.f : -0.25f, i ? 0.f : 0.5f, i ? 0.f : 0.75f, i ? 0.f : 1.f, 31.f};
EXPECT("builder LOD bias returned in float register", 1, P(nvnSamplerBuilderGetLodBias)(b) == (i ? 0.f : -2.25f));
P(nvnSamplerBuilderGetCompare)(b, &mode, &func);
EXPECT("builder compare mode written to caller", i ? NVN_COMPARE_MODE_NONE : NVN_COMPARE_MODE_COMPARE_R_TO_TEXTURE, mode);
EXPECT("builder compare function written to caller", i ? NVN_COMPARE_FUNC_LESS : NVN_COMPARE_FUNC_GEQUAL, func);
P(nvnSamplerBuilderGetBorderColor)(b, color + 1);
int equal = 1; for (int j = 0; j < 6; j++) if (color[j] != want[j]) equal = 0;
EXPECT("builder border writes exactly four floats", 1, equal);
EXPECT("builder anisotropy returned in float register", 1, P(nvnSamplerBuilderGetMaxAnisotropy)(b) == (i ? 1.f : 8.f));
EXPECT("builder reduction returned as enum", i ? NVN_SAMPLER_REDUCTION_AVERAGE : NVN_SAMPLER_REDUCTION_MAX, P(nvnSamplerBuilderGetReductionFilter)(b));
}
}

NVNsamplerBuilder sb; NVNsampler sampler;
P(nvnSamplerBuilderSetDefaults)(&sb);
const uint32_t opaque_black[4] = {0, 0, 0, 1};
Expand Down
1 change: 1 addition & 0 deletions docs/agents/symptoms.md
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,7 @@ One line per symptom in the [subsystem references](../reference/): what you see
- about one run in four stalled early (around the opening movie or the title), with no log output, not even the time-limit report. → [Dirty-page tracker race and early stalls](../reference/nvn-objects.md#dirty-page-tracker-race-and-early-stalls)
- a CPU-written texture stays stale after later writes; letters can be missing from a glyph cache. → [Dirty-page writes missed during upload](../reference/nvn-objects.md#dirty-page-writes-missed-during-upload)
- a host system call writing into storage after its NVN pool was finalized fails with `EFAULT`; a direct write can fault after the tracker stopped owning the page. → [A retired pool remains read-only](../reference/nvn-objects.md#a-retired-pool-remains-read-only)
- `[RED] NVN unimplemented function called: nvnSamplerBuilderGetLodBias`, `nvnSamplerBuilderGetCompare`, `nvnSamplerBuilderGetBorderColor`, `nvnSamplerBuilderGetMaxAnisotropy` or `nvnSamplerBuilderGetReductionFilter` during renderer setup. → [Sampler builder queries leave renderer state unread](../reference/nvn-objects.md#sampler-builder-queries-leave-renderer-state-unread)
- `[RED] NVN unimplemented function called: nvnSamplerBuilderSetBorderColorui` during renderer initialization. → [Integer sampler border colours](../reference/nvn-objects.md#integer-sampler-border-colours)
- `[RED] sampler ID 4096 not registered` (or another ID past the sampler pool), once, from the first frames on. → [Bound handles are the driver's 32-bit words](../reference/nvn-objects.md#bound-handles-are-the-drivers-32-bit-words)
- device / subsystem setup returns quietly and the next stage never starts. → [Version and capability checks that fail quietly](../reference/nvn-objects.md#version-and-capability-checks-that-fail-quietly)
Expand Down
2 changes: 2 additions & 0 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ The README covers packing and playing. This page is for working on nxnative itse
| iOS app | One unsigned IPA for iPhone and iPad. The rewritten code is embedded in the executable; the shader libraries, the RomFS and the game icon are inside the app. A settings screen comes before the game (`Launcher.swift`, drawn from `dm/launcher.json`, which `dm/games/settings.py` writes from `dm/games/settings.tsv`); the host's loading starts at app launch meanwhile, and the frame rate and render scale go into the frame step state when the game starts (`loader.c` `dm_fps_state_apply`) |
| Known gaps | Conditional render is always drawn; [indirect-count multi-draws](reference/rendering.md#indirect-count-multi-draws) can wait for a GPU-written count when the records need conversion, cannot be GPU-masked, or exceed the mask table capacity; geometry shaders do not translate. TBDR optimizations are off by default (they don't understand bindless textures yet). No amiibo. On the Mac, Mario's menu and dialogue text render blank (fine on the iPhone) |

NVN sampler builders expose their stored LOD bias, comparison settings, float border colour, maximum anisotropy and reduction filter through the corresponding getters, including after `SetDefaults` ([sampler builder queries](reference/nvn-objects.md#sampler-builder-queries-leave-renderer-state-unread)).

## Cheats

How a Switch with Atmosphère runs cheats, and where this host differs, is in [Cheats on a Switch](reference/cheats.md).
Expand Down
7 changes: 7 additions & 0 deletions docs/reference/nvn-objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,13 @@ Games read this count as a position in their own command memory and size their h

## NVN entry points

### Sampler builder queries leave renderer state unread

- **Symptom:** `[RED] NVN unimplemented function called: nvnSamplerBuilderGetLodBias`, `nvnSamplerBuilderGetCompare`, `nvnSamplerBuilderGetBorderColor`, `nvnSamplerBuilderGetMaxAnisotropy` or `nvnSamplerBuilderGetReductionFilter` during renderer setup.
- **Cause:** the setters stored these values, but the builder getters still reached the generic unimplemented handler. Output parameters were left untouched, and scalar results did not follow the getters' float or enum return signatures.
- **Fix:** the five getters read the builder's current sampler parameters through their typed NVN entry points, including the values restored by `SetDefaults`.
- **Found on:** [Digimon Story Time Stranger, issue #872](https://github.com/seedds/nxnative/issues/872), whose reporter identified these calls before an early crash. No repository profile exists yet. Archive extraction, rendering and the reported iPhone freeze are separate unresolved parts of that report; these getters alone do not establish that the game runs.

### Integer sampler border colours

- **Symptom:** `[RED] NVN unimplemented function called: nvnSamplerBuilderSetBorderColorui` during renderer initialization.
Expand Down
Loading