mirror of
https://github.com/mitch030504/Wiicompiled_VR_Frame.git
synced 2026-10-06 02:00:14 +02:00
Merge upstream/main into openxr-work (reverse-Z fix adapted for VR)
Brings in patchzyy/Wiicompiled main: os_sleep parked-thread fix (#195), HTTPS Retro WFC payload (#198), macOS build guide (#177), and the reverse-Z depth fix (#134). Conflicts were in aurora-main/lib/gfx/common.cpp and lib/gx/shader.cpp, both from #134, which lands squarely on the VR stereo replay path. #134 makes UseReversedZ genuinely reversed: the near/far correction now applies exactly once, inside effective_projection(), instead of being applied there AND per-vertex in the shader (the double application had been cancelling out, so "reversed" Z silently behaved like forward Z). Three pieces of the VR path were built against that old behaviour and would have broken silently, so they are adapted here: - shader.cpp exact-screen-depth parked the virtual screen at -0.5*w specifically so the shader's following negation would land it at +0.5*w. With that negation gone it now writes +0.5*w directly; keeping the minus sign would park the screen at NDC -0.5, outside the clip volume, discarding every 2D/HUD draw. - stereo_replay.hpp backend_ndc_depth_row re-applied the correction to the projection it was handed. That projection is effective_projection() output, which now already carries it, so the function is a pass-through of the Z row and no longer depends on the reversed-Z setting; the dead bool parameter is dropped. Re-applying it would invert the virtual screen's depth ordering, so 2D layers meant to sit on top would lose the depth test to the ones behind them. - shader_info.cpp stages the host depth window for that exact-depth path. It now uses the same reversed-Z remap as upstream's new SetViewport code, since frag_depth is written directly and has to reproduce the window the fixed viewport transform would have applied. Restricted depth windows (how the game forces an element in front of everything) are exactly the 2D draws the virtual screen carries. The SetViewport resolution keeps upstream's remap but retains the ordering/clamp guard our version had: for any ordered guest range the result is identical to upstream, and it avoids handing WebGPU minDepth > maxDepth for the swapped pair MKW is known to emit. The VR eye replay reuses these recorded values, so the guard covers that path too. Test updates: - stereo_replay_test now asserts the composed Z row against the staged projection's own Z row rather than against the helper's output, so it actually catches a re-introduced double correction (verified: it fails when the old negation is put back; the previous self-consistent form passed). - gx_fifo_test's clearDepthValue expectation followed #134's deliberate clear_depth_value() inversion, expressed through UseReversedZ rather than hardcoded. Upstream changed the behaviour without updating this test, so it fails on upstream/main as-is. Verified: aurora suite 247 passed with the same 2 failures that already fail on the pre-merge branch (IndexedPaletteHistoryKeepsAbsoluteVertexSlots, PacksOneUniformWhenBothHalvesNeedInitialValue - both pre-existing, unrelated to depth); shader.cpp and common.cpp compile clean; translator suite 577 passed. Not yet validated on-device in VR. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
commit
c8eaa52727
22 files changed
+635
-71
No files matched your search
@@ -990,19 +990,27 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config) noexcept {
|
||||
"\n let clip_base = select(clip_a, clip_b, use_b);"
|
||||
"\n out.pos = vec4f(clip_base.xy + offset_ndc * clip_base.w, clip_base.zw);";
|
||||
}
|
||||
// The near/far depth correction used to be applied here per-vertex (out.pos.z = -out.pos.z for
|
||||
// reversed, or += out.pos.w for forward), redundantly on top of the same correction already
|
||||
// folded into ubuf.proj by effective_projection() (shader_info.cpp) - applying it twice canceled
|
||||
// out for the common case (any draw where effective_projection() decides to flip), silently
|
||||
// making "reversed" Z behave identically to forward Z. It is now applied exactly once, in the
|
||||
// projection matrix alone (matching upstream aurora commit 1dde08fa: "Move depth correction to
|
||||
// projection matrix"), so nothing needs to happen to out.pos.z here.
|
||||
if (config.exactScreenDepth) {
|
||||
vtxOutAttrs += fmt::format("\n @location({}) @interpolate(flat) exact_screen_depth: f32,", vtxOutIdx++);
|
||||
// Virtual-screen composition stores the original backend-convention NDC
|
||||
// depth in the otherwise replaceable projection Z row. Capture it before
|
||||
// parking raster depth at midrange; this avoids growing every GX uniform.
|
||||
//
|
||||
// The parked value is written directly as +0.5 * w now that the per-vertex
|
||||
// depth correction above is gone. It used to be -0.5 * w specifically so the
|
||||
// `out.pos.z = -out.pos.z` that followed would land it at +0.5 * w; with
|
||||
// that negation removed, keeping the minus sign would park the virtual
|
||||
// screen at NDC -0.5, outside the clip volume, and discard every 2D draw.
|
||||
vtxXfrAttrsPre +=
|
||||
"\n out.exact_screen_depth = clamp(out.pos.z, 0.0, 1.0);"
|
||||
"\n out.pos.z = -0.5 * out.pos.w;";
|
||||
}
|
||||
if constexpr (UseReversedZ) {
|
||||
vtxXfrAttrsPre += "\n out.pos.z = -out.pos.z;";
|
||||
} else {
|
||||
vtxXfrAttrsPre += "\n out.pos.z += out.pos.w;";
|
||||
"\n out.pos.z = 0.5 * out.pos.w;";
|
||||
}
|
||||
// GX rasterizes at a 7/12 pixel center when antialiasing is disabled, while WebGPU rasterizes at 1/2.
|
||||
vtxXfrAttrsPre +=
|
||||
@@ -1469,8 +1477,18 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config) noexcept {
|
||||
textureDependency.texMapId, uvIn);
|
||||
}
|
||||
|
||||
std::string fogDepthExpr = UseReversedZ ? "in.pos.z" : "(1.0 - in.pos.z)";
|
||||
std::string fogZCoordExpr = fmt::format("u32(round(clamp({}, 0.0, 1.0) * 16777216.0))", fogDepthExpr);
|
||||
|
||||
// in.pos.z is the host NDC z (forward: 0=near/1=far; reversed: 1=near/0=far post-fix), but this
|
||||
// expression needs to produce GX's own native distance term (always 0=near/1=far, matching how
|
||||
// g_gxState.clearDepth/clear_depth_value() are interpreted before their own UseReversedZ
|
||||
// inversion) - forward already matches directly; reversed needs the same 1-x flip everything
|
||||
// else reversed-Z-aware uses. This was backwards (verified directly against upstream aurora's
|
||||
// identical expression in build_shader_source), which fed both fog density and the GX_ZT_ADD
|
||||
// z-texture path the wrong distance value.
|
||||
std::string fogDepthExpr = UseReversedZ ? "(1.0 - in.pos.z)" : "in.pos.z";
|
||||
std::string fogZCoordExpr =
|
||||
fmt::format("u32(round(clamp({}, 0.0, 1.0) * 16777216.0))", fogDepthExpr);
|
||||
|
||||
if (usesZTextureDepth) {
|
||||
const u32 zTexBias = config.zTexture & 0x00FFFFFFu;
|
||||
const u32 zTexFmt = (config.zTexture >> 24) & 0x3u;
|
||||
@@ -1501,7 +1519,7 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config) noexcept {
|
||||
fragmentFn += fmt::format(
|
||||
"\n let oldZ = u32(round(clamp({0}, 0.0, 1.0) * 16777216.0));"
|
||||
"\n ztexCoord = (ztexCoord + oldZ) & 0x00ffffffu;",
|
||||
UseReversedZ ? "in.pos.z" : "(1.0 - in.pos.z)");
|
||||
UseReversedZ ? "(1.0 - in.pos.z)" : "in.pos.z");
|
||||
}
|
||||
fragmentFn += "\n let ztexDepth = f32(ztexCoord) / 16777216.0;";
|
||||
fogZCoordExpr = "ztexCoord";
|
||||
@@ -1645,12 +1663,22 @@ wgpu::ShaderModule build_shader(const ShaderConfig& config) noexcept {
|
||||
|
||||
if (config.exactScreenDepth) {
|
||||
// Fragment depth is already in window coordinates. Reapply the recorded
|
||||
// viewport's clamped depth window exactly as the fixed pipeline did.
|
||||
// viewport's clamped depth window exactly as the fixed pipeline did. This
|
||||
// value never passed through the per-vertex depth correction upstream
|
||||
// removed, so it needs no reversed-Z adjustment of its own - the recorded
|
||||
// range it is rebuilt from is already reversed-Z-aware (see the SetViewport
|
||||
// remap in gfx/common.cpp).
|
||||
fragmentFn +=
|
||||
"\n let fragDepth = ubuf.exact_screen_depth_range.x + "
|
||||
"in.exact_screen_depth * ubuf.exact_screen_depth_range.y;";
|
||||
} else {
|
||||
fragmentFn += fmt::format("\n let fragDepth = {}ztexDepth;", UseReversedZ ? "" : "1.0 - ");
|
||||
// ztexDepth is in GX's native distance terms (0=near/1=far, see fogDepthExpr's comment
|
||||
// above), but frag_depth must be written in the same host NDC-z convention in.pos.z itself
|
||||
// uses - forward matches directly (no change), reversed needs the same 1-x flip. This was
|
||||
// backwards the same way fogDepthExpr was (verified by the same derivation, since aurora
|
||||
// upstream has no directly equivalent line here to cross-check against - this
|
||||
// z-texture-depth-output path appears to be specific to this fork).
|
||||
fragmentFn += fmt::format("\n let fragDepth = {}ztexDepth;", UseReversedZ ? "1.0 - " : "");
|
||||
}
|
||||
fragmentReturnType = "FragmentOutput";
|
||||
fragmentReturn =
|
||||
|
||||
Reference in new issue
Block a user