summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2023-11-12 22:18:10 -0600
committerAlejandro Soto <alejandro@34project.org>2023-11-14 07:48:52 -0600
commit58d647a047e8761ad1f619173ee51dd4b65831ac (patch)
treee3a08d6321da9a031caf81d84a59ca4f05823fa9
parenta401d413ba766b01aa980a8e013c79500a490c2e (diff)
rtl/gfx: implement perspective-corrected barycentric coordinates
-rw-r--r--gfx_hw.tcl1
-rw-r--r--rtl/gfx/gfx_defs.sv6
-rw-r--r--rtl/gfx/gfx_frag.sv34
-rw-r--r--rtl/gfx/gfx_frag_bary.sv78
4 files changed, 105 insertions, 14 deletions
diff --git a/gfx_hw.tcl b/gfx_hw.tcl
index 0836a80..ffe9a43 100644
--- a/gfx_hw.tcl
+++ b/gfx_hw.tcl
@@ -72,6 +72,7 @@ add_fileset_file gfx_clear.sv SYSTEM_VERILOG PATH rtl/gfx/gfx_clear.sv
add_fileset_file gfx_lerp.sv SYSTEM_VERILOG PATH rtl/gfx/gfx_lerp.sv
add_fileset_file gfx_frag.sv SYSTEM_VERILOG PATH rtl/gfx/gfx_frag.sv
add_fileset_file gfx_frag_addr.sv SYSTEM_VERILOG PATH rtl/gfx/gfx_frag_addr.sv
+add_fileset_file gfx_frag_bary.sv SYSTEM_VERILOG PATH rtl/gfx/gfx_frag_bary.sv
add_fileset_file gfx_frag_shade.sv SYSTEM_VERILOG PATH rtl/gfx/gfx_frag_shade.sv
add_fileset_file gfx_frag_funnel.sv SYSTEM_VERILOG PATH rtl/gfx/gfx_frag_funnel.sv
diff --git a/rtl/gfx/gfx_defs.sv b/rtl/gfx/gfx_defs.sv
index bffbb1f..7da259a 100644
--- a/rtl/gfx/gfx_defs.sv
+++ b/rtl/gfx/gfx_defs.sv
@@ -67,6 +67,10 @@ typedef struct packed
typedef logic signed[31:0] fixed;
typedef fixed[2:0] fixed_tri;
+`define EDGE_P0_TO_P1 0
+`define EDGE_P1_TO_P2 1
+`define EDGE_P2_TO_P0 2
+
typedef struct packed
{
fixed x, y;
@@ -134,6 +138,8 @@ typedef struct packed
} frag_paint;
`define GFX_FRAG_ADDR_STAGES 3
+`define GFX_FRAG_BARY_STAGES (`FIXED_DIV_STAGES + 2 + `FIXED_DIV_STAGES)
`define GFX_FRAG_SHADE_STAGES (`LERP_STAGES + 1)
+`define GFX_FRAG_STAGES (`GFX_FRAG_BARY_STAGES + `GFX_FRAG_SHADE_STAGES)
`endif
diff --git a/rtl/gfx/gfx_frag.sv b/rtl/gfx/gfx_frag.sv
index b4481ce..79fb2b4 100644
--- a/rtl/gfx/gfx_frag.sv
+++ b/rtl/gfx/gfx_frag.sv
@@ -20,17 +20,17 @@ module gfx_frag
gfx_frag_funnel funnel
(
.frag(funnel_frag),
- .out_ready(addr_ready),
+ .out_ready(frag_ready),
.out_valid(funnel_valid),
.*
);
- logic addr_ready, addr_stall;
+ logic frag_ready, frag_stall;
- gfx_pipeline_flow #(.STAGES(`GFX_FRAG_SHADE_STAGES)) addr_flow
+ gfx_pipeline_flow #(.STAGES(`GFX_FRAG_STAGES)) addr_flow
(
- .stall(addr_stall),
- .in_ready(addr_ready),
+ .stall(frag_stall),
+ .in_ready(frag_ready),
.in_valid(funnel_valid),
.out_ready(1),
.out_valid(),
@@ -42,28 +42,34 @@ module gfx_frag
gfx_frag_addr addr
(
.frag(funnel_frag),
- .stall(addr_stall),
+ .stall(frag_stall),
.*
);
- localparam ADDR_WAIT_Z_STAGES = `GFX_FRAG_SHADE_STAGES - `GFX_FRAG_ADDR_STAGES;
+ localparam ADDR_WAIT_STAGES = `GFX_FRAG_STAGES - `GFX_FRAG_ADDR_STAGES;
- gfx_pipes #(.WIDTH($bits(linear_coord)), .DEPTH(ADDR_WAIT_Z_STAGES)) addr_pipes
+ gfx_pipes #(.WIDTH($bits(linear_coord)), .DEPTH(ADDR_WAIT_STAGES)) addr_pipes
(
.in(linear),
.out(),
- .stall(addr_stall),
+ .stall(frag_stall),
.*
);
- gfx_frag_shade shade
+ fixed b1, b2;
+
+ gfx_frag_bary bary
(
- .stall(addr_stall),
+ .ws(),
+ .edges(),
+ .stall(frag_stall),
+ .*
+ );
- .b1(),
- .b2(),
+ gfx_frag_shade shade
+ (
+ .stall(frag_stall),
.color(),
-
.argb0(),
.argb1_argb0(),
.argb2_argb0(),
diff --git a/rtl/gfx/gfx_frag_bary.sv b/rtl/gfx/gfx_frag_bary.sv
new file mode 100644
index 0000000..5004866
--- /dev/null
+++ b/rtl/gfx/gfx_frag_bary.sv
@@ -0,0 +1,78 @@
+`include "gfx/gfx_defs.sv"
+
+module gfx_frag_bary
+(
+ input logic clk,
+
+ input fixed_tri edges,
+ ws,
+ input logic stall,
+
+ output fixed b1,
+ b2
+);
+
+ fixed area, b0_w0, b1_w1, b2_w2, b1_w1_b2_w2, hold_b0_w0, hold_b1_w1, hold_b2_w2;
+ fixed_tri bs_ws, orthographic_bs;
+
+ assign b0_w0 = bs_ws[0];
+ assign b1_w1 = bs_ws[1];
+ assign b2_w2 = bs_ws[2];
+
+ assign orthographic_bs[0] = edges[`EDGE_P1_TO_P2];
+ assign orthographic_bs[1] = edges[`EDGE_P2_TO_P0];
+ assign orthographic_bs[2] = edges[`EDGE_P0_TO_P1];
+
+ genvar i;
+ generate
+ for (i = 0; i < 3; ++i) begin: vertices
+ gfx_fixed_div div_b_w
+ (
+ .z(orthographic_bs[i]),
+ .d(ws[i]),
+ .q(bs_ws[i]),
+ .*
+ );
+ end
+ endgenerate
+
+ localparam AREA_STAGES = 2;
+
+ gfx_pipes #(.WIDTH($bits(fixed)), .DEPTH(AREA_STAGES)) b1_w1_pipes
+ (
+ .in(b1_w1),
+ .out(hold_b1_w1),
+ .*
+ );
+
+ gfx_pipes #(.WIDTH($bits(fixed)), .DEPTH(AREA_STAGES)) b2_w2_pipes
+ (
+ .in(b2_w2),
+ .out(hold_b2_w2),
+ .*
+ );
+
+ gfx_fixed_div norm_b1
+ (
+ .z(hold_b1_w1),
+ .d(area),
+ .q(b1),
+ .*
+ );
+
+ gfx_fixed_div norm_b2
+ (
+ .z(hold_b2_w2),
+ .d(area),
+ .q(b2),
+ .*
+ );
+
+ always_ff @(posedge clk)
+ if (!stall) begin
+ area <= hold_b0_w0 + b1_w1_b2_w2;
+ hold_b0_w0 <= b0_w0;
+ b1_w1_b2_w2 <= b1_w1 + b2_w2;
+ end
+
+endmodule