Give mesh output components outside the program's output map Maxwell's default of (0, 0, 0, 1).

A mesh program's header lists the components of each output vector it has; the fragment stage may read the others.
The native mesh entry function never wrote them, so they read as whatever the output held, and the fallback's vertex
stage wrote 0 for all of them, w included. Maxwell gives an unwritten component (0, 0, 0, 1), as the pipeline code
already pads a missing vertex output. Both paths now write that default: MeshSpirv.cs after copying each vertex's lines,
mesh_fb.c meshfb_vs with w as the bits of 1.0f whatever the type.

Checked: all 520 task and mesh programs of an installed shader cache translate and pass spirv-val (vulkan1.3); 500
mesh modules gained about 730 bytes each on average, so many of the game's mesh programs have partly listed vectors.
--probe-meshfb passes (fallback pictures equal the mesh pipeline's), and its module part converts all 520 new
translations with 0 failures, all 1,020 modules pass spirv-val and their compute pipelines build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
chrg6
2026-11-11 17:03:41 -05:00
parent e92f0ae3f1
commit e8b4d29f91
3 changed files with 21 additions and 2 deletions

View File

@@ -121,7 +121,11 @@ Grep-level look on 2026-10-22, statuses updated 2026-10-26; "saw" is what the gr
not just their base location: an FS `vec4[16]` requires all 16 locations even when it only accesses some elements.
The same reflected mask feeds recorded-pipeline prewarm, independent stage-library unions and direct pipeline builds.
Our translator never links stages, so its `InitializeVertexOutputs` would initialise no user output;
translator patch 0006 initialises the unlinked outputs. **Implemented; array-span runtime validation pending.**
translator patch 0006 initialises the unlinked outputs. Mesh programs: a component of a position or generic vector
that the program's output map leaves out is written as (0, 0, 0, 1) by the mesh entry function
(`tools/xlate/MeshSpirv.cs`) and by the fallback's vertex stage (`runtime/mesh_fb.c` `meshfb_vs`); a whole location
the fragment stage reads and the mesh program lacks is still not padded with mesh shaders (`have = ~0u` for mesh in
`vk_pipeline.c`). **Implemented; array-span runtime validation pending.**
3. **Masked clears.** `vk_exec.c` skips colour clears with a partial channel mask (`W_CLEAR_MASK`); `clear_ds` skips stencil
clears with a partial mask (`W_STENCIL_MASK`). NX2navi issues such clears. Check the log for
`colour clear with channel mask` and `stencil clear with mask`. The hardware recipe (1.3) shows what the replay must do: colour clear = scissor 0 + channel mask, stencil clear = `value & mask` merged under the front write mask; so a draw with `colorWriteMask` / `stencilWriteMask` set to the clear mask is the exact equivalent. **Missing.**

View File

@@ -583,9 +583,11 @@ uint32_t *meshfb_vs(const MeshFbInfo *m, uint32_t out_mask, const uint8_t out_ty
for (int g = 0; g < 32; g++) {
if (!loc_var[g]) continue;
int t = out_type[g] < 3 ? out_type[g] : 0;
// A component outside the program's output map reads as Maxwell gives an unwritten one: (0, 0, 0, 1), the w
// as the bits of 1.0f whatever the type, as vk_pipeline.c spirv_add_outputs pads a missing output.
uint32_t comp[4];
for (int k = 0; k < 4; k++) {
uint32_t word_k = gen[g][k] ? gen[g][k] : k0;
uint32_t word_k = gen[g][k] ? gen[g][k] : k == 3 ? K(&c, 0x3f800000) : k0;
comp[k] = t == 2 ? word_k : E(&c, OpBitcast, t_scalar[t], word_k);
}
DO(&c, OpStore, loc_var[g], E(&c, OpCompositeConstruct, t_v4[t], comp[0], comp[1], comp[2], comp[3]));

View File

@@ -306,6 +306,9 @@ static class MeshSpirv
// outputs
uint tV4 = Ty(OpTypeVector, tFloat, 4);
uint pOutFloat = Ptr(ScOutput, tFloat);
uint fZero = Id(), fOne = Id();
globals.Add(new Insn(OpConstant, new[] { tFloat, fZero, 0u }));
globals.Add(new Insn(OpConstant, new[] { tFloat, fOne, 0x3f800000u }));
uint posVar = 0, sizeVar = 0;
var generic = new Dictionary<int, uint>();
foreach (int a in m.Lines)
@@ -343,6 +346,16 @@ static class MeshSpirv
uint ptr = comp == uint.MaxValue ? Emit(OpAccessChain, pOutFloat, var, v) : Emit(OpAccessChain, pOutFloat, var, v, C(comp));
Do(OpStore, ptr, value);
}
// A component of an output vector that the program's output map leaves out reads as Maxwell gives an
// unwritten one, (0, 0, 0, 1), instead of whatever the output held.
void Defaults(uint var, int first)
{
for (int k = 0; k < 4; k++)
if (!m.Lines.Contains(first + 4 * k))
Do(OpStore, Emit(OpAccessChain, pOutFloat, var, v, C((uint)k)), k == 3 ? fOne : fZero);
}
if (posVar != 0) Defaults(posVar, 0x70);
foreach (var (g, var) in generic) Defaults(var, 0x80 + 16 * g);
});
}
for (int k = 0; k * threads < maxP; k++)