Snapshot: fog implementation + fidelity tooling baseline (pre bilinear-clamp fix)
Per-vertex GS fog end-to-end (gs_stub emit incl. persp_emit5, gs_prim_list_feeder XYZ2->XYZF2 on PRIM.FGE, gs_make_sh3_scheduler_fixture.py F/FGE packing), new fog TBs, fidelity attribution tooling. Functional baseline before removing the dead bilinear lerp8 clamps (Codex: 161-node comb loop -> -0.042ns setup fail). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -502,9 +502,10 @@ module gs_texture_unit #(
|
||||
// beat[k]'s 32-bit ABGR word -> capture into tap[k].
|
||||
// If k<3: k++ and -> ISSUE (next neighbor). If k==3: -> DONE.
|
||||
// DONE : combinationally lerp the 4 captured taps by u_frac/v_frac
|
||||
// per channel; assert out_valid for 1 cycle with tex_color;
|
||||
// drop busy; -> IDLE.
|
||||
// => total ~ 4*(1+L)+1 cycles per filtered sample. Throughput is NOT a
|
||||
// per channel and capture the result in tex_color_hold.
|
||||
// OUT : assert out_valid for 1 cycle with the registered color;
|
||||
// -> IDLE.
|
||||
// => total ~ 4*(1+L)+2 cycles per filtered sample. Throughput is NOT a
|
||||
// goal here (a later texture-cache pass collapses the 4 reads).
|
||||
//
|
||||
// Neighbor table (k -> du,dv): 0->(0,0) 1->(1,0) 2->(0,1) 3->(1,1).
|
||||
@@ -519,12 +520,13 @@ module gs_texture_unit #(
|
||||
// then defensively clamped to 0..255.
|
||||
generate
|
||||
if (BILINEAR_ENABLE) begin : g_bilinear
|
||||
localparam logic [1:0] BS_IDLE = 2'd0;
|
||||
localparam logic [1:0] BS_ISSUE = 2'd1;
|
||||
localparam logic [1:0] BS_WAIT = 2'd2;
|
||||
localparam logic [1:0] BS_DONE = 2'd3;
|
||||
localparam logic [2:0] BS_IDLE = 3'd0;
|
||||
localparam logic [2:0] BS_ISSUE = 3'd1;
|
||||
localparam logic [2:0] BS_WAIT = 3'd2;
|
||||
localparam logic [2:0] BS_DONE = 3'd3;
|
||||
localparam logic [2:0] BS_OUT = 3'd4;
|
||||
|
||||
logic [1:0] state;
|
||||
logic [2:0] state;
|
||||
logic [1:0] beat; // which neighbor 0..3
|
||||
logic [31:0] wait_cnt; // counts RD_LATENCY
|
||||
logic [31:0] tap [0:3]; // captured ABGR per neighbor
|
||||
@@ -641,7 +643,13 @@ module gs_texture_unit #(
|
||||
wait_cnt <= wait_cnt + 32'd1;
|
||||
end
|
||||
end
|
||||
default: begin // BS_DONE
|
||||
BS_DONE: begin
|
||||
// tex_color_hold captures the finished blend on this
|
||||
// edge. Keep a distinct OUT cycle so no consumer can
|
||||
// see the tap->two-lerp combinational cone directly.
|
||||
state <= BS_OUT;
|
||||
end
|
||||
default: begin // BS_OUT
|
||||
state <= BS_IDLE;
|
||||
end
|
||||
endcase
|
||||
@@ -703,18 +711,15 @@ module gs_texture_unit #(
|
||||
cv_a = lerp8(top_a, bot_a, lat_vf);
|
||||
end
|
||||
|
||||
// Ch310 — HOLD register for the filtered color. The combined-renderer
|
||||
// Ch310/Ch422 — HOLD register for the filtered color. The combined-renderer
|
||||
// FSM (gs_stub CB_TWAIT) may latch the result a cycle or two AFTER the
|
||||
// out_valid pulse (it steps at half-rate on z_advance beats), so the
|
||||
// blended ABGR must stay STABLE from out_valid until the next sample.
|
||||
// tex_color is the LIVE combinational blend during DONE (so an
|
||||
// out_valid-keyed caller — tb_gs_texture_bilinear — reads the fresh
|
||||
// value the SAME cycle out_valid pulses, byte-identical to before) and
|
||||
// the LATCHED copy afterward (so a caller that reads one+ cycles later,
|
||||
// like CB_TWAIT→CB_T, still sees it). The register captures the blend
|
||||
// on the clk edge that LEAVES DONE; combining "live during DONE, held
|
||||
// after" gives a value stable from out_valid until the next sample
|
||||
// overwrites it at its DONE.
|
||||
// The register captures the blend on the clk edge that LEAVES DONE.
|
||||
// Ch422 makes OUT a separate following cycle, so tex_color and
|
||||
// out_valid expose only this registered value. That is the timing
|
||||
// boundary between the two-stage bilinear arithmetic and downstream
|
||||
// TEX0 modulation; callers already wait on out_valid or !busy.
|
||||
logic [31:0] tex_color_blend;
|
||||
assign tex_color_blend = {cv_a, cv_b, cv_g, cv_r};
|
||||
logic [31:0] tex_color_hold;
|
||||
@@ -724,9 +729,9 @@ module gs_texture_unit #(
|
||||
else if (state == BS_DONE)
|
||||
tex_color_hold <= tex_color_blend; // capture the just-blended value
|
||||
end
|
||||
// live during the DONE pulse, held (last captured) otherwise
|
||||
// Registered result, held until the next sample completes.
|
||||
logic [31:0] tex_color_lin;
|
||||
assign tex_color_lin = (state == BS_DONE) ? tex_color_blend : tex_color_hold;
|
||||
assign tex_color_lin = tex_color_hold;
|
||||
|
||||
// --- output mux: bilinear FSM owns the outputs for a FILTERED PSMCT32
|
||||
// sample (do_lin). When do_lin=0 — non-PSMCT32 psm OR MMAG=0 NEAREST —
|
||||
@@ -738,7 +743,7 @@ module gs_texture_unit #(
|
||||
// tex_rd_addr is the SAME addr-gen output for both paths (the wrap
|
||||
// selects beat_u/beat_v vs port u/v); the FSM just gates rd_en.
|
||||
assign tex_rd_addr = near_rd_addr;
|
||||
assign out_valid = do_lin ? (state == BS_DONE) : near_out_valid;
|
||||
assign out_valid = do_lin ? (state == BS_OUT) : near_out_valid;
|
||||
assign tex_color = do_lin ? tex_color_lin : near_color;
|
||||
assign busy = do_lin && (state != BS_IDLE);
|
||||
end else begin : g_nearest
|
||||
|
||||
Reference in New Issue
Block a user