Replace the synthetic placeholder triangle in the --ui window with the
splash's REAL guest geometry, proving the faithful-render pipe end to end.
Architecture: Route A (UI-side replay). A per-draw capture channel carries
each PM4_DRAW_INDX*'s real state to the UI, which replays it through the
existing wgpu Xenos pipeline. The deterministic headless core is untouched:
capture is gated on an Option<Vec<DrawCapture>> that is None in headless
mode and only enabled on the --ui path, so the --gpu-inline n50m golden is
byte-identical (verified 2x).
The hard part was sourcing real vertices. The WGSL VS already does
format-aware vertex fetch from the b4 storage buffer at the address from the
fetch constant -- but b4 was never populated and the fetch address is an
absolute guest dword address. The slice:
* xenia-gpu/draw_capture.rs: parse the active VS, find its first vertex
fetch, read that fetch constant, copy a bounded window of guest memory
at the fetch base. Best-effort: has_real_vertices=false falls back to
procedural geometry (never fabricated pixels).
* gpu_system.rs: accumulate one DrawCapture per draw into frame_captures.
* exports.rs (vd_swap): drain + publish the frame's captures to the UI.
* ui_bridge/bridge.rs: new publish_geometry channel + UiHandles.geometry.
* WGSL (interp + translator): rebase the absolute fetch address by a new
DrawConstants.vertex_base_dwords so it indexes the uploaded window.
* render.rs: dispatch_xenos_captures uploads each draw's real vertex
window + matching shader, issues real DrawRequests (real prim type,
host vertex count, vs/ps keys).
* app.rs: prefer the real-capture replay; HUD adds real-geo=N counter.
Verified in --ui on Sylpheed: "first Xenos capture batch replayed (real
geometry) captures=24 real_vertex_draws=24" -- all draws resolved a real
guest vertex window; WGSL compiles; no validation errors over 1616 swaps.
Still synthetic-free but not yet pixel-perfect: textures/UVs, DMA index
buffers (auto-index only for now), and kCopy resolve routing are staged
for follow-ups. Faithful: real vertex data, prim types, shaders, constants.
cargo test --workspace green; n50m golden unchanged (2x byte-identical).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
51 lines
1.6 KiB
Rust
51 lines
1.6 KiB
Rust
//! Xenos GPU emulation for xenia-rs.
|
|
//!
|
|
//! Modules:
|
|
//! - [`pm4`]: packet format decoder + Type-3 opcode set.
|
|
//! - [`ring_view`]: ring-buffer bookkeeping (base/size/read/write pointers).
|
|
//! - [`register_file`]: 0x6000-entry register array backing the CP + state.
|
|
//! - [`gpu_system`]: top-level `GpuSystem` + PM4 executor running one packet
|
|
//! per call (see the plan's P2 for the design rationale).
|
|
//!
|
|
//! Legacy module `ring_drain` and `command_processor` are retained while P3+
|
|
//! migrations finish; they will be removed once every caller is on
|
|
//! [`gpu_system::GpuSystem`].
|
|
|
|
pub mod command_processor;
|
|
pub mod draw_capture;
|
|
pub mod draw_state;
|
|
pub mod edram;
|
|
pub mod gpu_system;
|
|
pub mod handle;
|
|
pub mod mmio_region;
|
|
pub mod pm4;
|
|
pub mod primitive;
|
|
pub mod register_file;
|
|
pub mod ring_drain;
|
|
pub mod ring_view;
|
|
pub mod render_target_cache;
|
|
pub mod resolve;
|
|
pub mod shader_metrics;
|
|
pub mod shaders;
|
|
pub mod texture_cache;
|
|
pub mod tiled_address;
|
|
pub mod translator;
|
|
pub mod ucode;
|
|
pub mod xenos_constants;
|
|
|
|
pub use gpu_system::{
|
|
ExecOutcome, GpuBlock, GpuMmio, GpuStats, GpuSystem, InterruptSource, PendingInterrupt,
|
|
PHYSICAL_BACKING_BASE, ShaderBlob, SwapNotification, WaitCmp, physical_to_backing,
|
|
};
|
|
pub use handle::{
|
|
DrainReply, GpuBackend, GpuCommand, GpuDigestSnapshot, GpuHandle, GpuWorker,
|
|
shutdown_and_join_with_timeout, spawn_gpu_worker, spawn_noop_worker,
|
|
};
|
|
pub use mmio_region::build_region as build_mmio_region;
|
|
pub use pm4::{
|
|
PacketHeader, PacketKind, PM4_INTERRUPT, PM4_NOP, PM4_XE_SWAP, SWAP_SIGNATURE,
|
|
type3_opcode_name,
|
|
};
|
|
pub use ring_drain::{DrainResult, drain};
|
|
pub use ring_view::RingBufferView;
|