aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--camera.c17
-rw-r--r--doc/libgraphics.ms175
-rw-r--r--doc/libgraphics.pdfbin15087 -> 19045 bytes
-rw-r--r--doc/libgraphics.ps597
-rw-r--r--fb.c43
-rw-r--r--graphics.h57
-rw-r--r--internal.h25
-rw-r--r--render.c483
-rw-r--r--scene.c42
-rw-r--r--util.c2
-rw-r--r--viewport.c9
11 files changed, 1183 insertions, 267 deletions
diff --git a/camera.c b/camera.c
index 67bca08..9b4c1ef 100644
--- a/camera.c
+++ b/camera.c
@@ -21,6 +21,16 @@ updatestats(Camera *c, uvlong v)
}
static void
+updatetimes(Camera *c, Renderjob *j)
+{
+ c->times.R[c->times.cur] = j->times.R;
+ c->times.E[c->times.cur] = j->times.E;
+ c->times.Tn[c->times.cur] = j->times.Tn;
+ c->times.Rn[c->times.cur] = j->times.Rn;
+ c->times.cur = ++c->times.cur % nelem(c->times.R);
+}
+
+static void
verifycfg(Camera *c)
{
assert(c->vp != nil);
@@ -86,7 +96,7 @@ shootcamera(Camera *c, Shadertab *s)
job = emalloc(sizeof *job);
memset(job, 0, sizeof *job);
- job->fb = c->vp->fbctl->fb[c->vp->fbctl->idx^1]; /* address the back buffer */
+ job->fb = c->vp->fbctl->getbb(c->vp->fbctl);
job->scene = c->s;
job->shaders = s;
job->donec = chancreate(sizeof(void*), 0);
@@ -98,8 +108,9 @@ shootcamera(Camera *c, Shadertab *s)
t1 = nanosec();
c->vp->fbctl->swap(c->vp->fbctl);
+ updatestats(c, t1-t0);
+ updatetimes(c, job);
+
chanfree(job->donec);
free(job);
-
- updatestats(c, t1-t0);
}
diff --git a/doc/libgraphics.ms b/doc/libgraphics.ms
index 87a23a7..31a44af 100644
--- a/doc/libgraphics.ms
+++ b/doc/libgraphics.ms
@@ -2,33 +2,152 @@
libgraphics
.AU
Rodrigo G. López
-.sp
rgl@antares-labs.eu
-.AI
-Antares Telecom Laboratories
-Albatera, Alicante
-.FS
-ACHTUNG! this is a
-.B "WORK IN PROGRESS"
-.FE
-.NH 1
-Data Structures
-.NH 2
-Camera
-.P1
-struct Camera {
- RFrame3; /* VCS */
- Image *viewport;
- double fov; /* vertical FOV */
- struct {
- double n, f; /* near and far clipping planes */
- } clip;
- Projection ptype;
- Matrix3 proj; /* VCS to viewport xform */
-};
-.P2
+.AB
+To be determined.
+.AE
+.SH
+Rendering graph
.PP
-A camera is an image capturing entity, analog to the real world device
-we all know, that allows us to see the virtual 3-D world by projecting
-it into a viewport we can attach to a screen or window for real-time
-visualization or write out into a file.
+.PS
+.ps 7
+circlerad = 0.3
+moveht = 0.1
+box "Renderjob"
+arrow
+R: circle "renderer"
+arrow
+E: circle "entityproc"
+move
+Tiler: [
+ down
+ T0: circle "tiler 0"
+ move
+ T1: circle "tiler 1"
+ move
+ Td: circle "…"
+ move
+ Tn: circle "tiler n"
+]
+move
+Raster: [
+ down
+ R0: circle "rasterizer 0"
+ move
+ R1: circle "rasterizer 1"
+ move
+ Rd: circle "…"
+ move
+ Rn: circle "rasterizer n"
+]
+arrow from E to Tiler.T0 chop
+arrow from E to Tiler.T1 chop
+arrow from E to Tiler.Td chop
+arrow from E to Tiler.Tn chop
+arrow from Tiler.T0 to Raster.R0 chop
+arrow from Tiler.T0 to Raster.R1 chop
+arrow from Tiler.T0 to Raster.Rd chop
+arrow from Tiler.T0 to Raster.Rn chop
+arrow from Tiler.T1 to Raster.R0 chop
+arrow from Tiler.T1 to Raster.R1 chop
+arrow from Tiler.T1 to Raster.Rd chop
+arrow from Tiler.T1 to Raster.Rn chop
+.ps 10
+.PE
+.B "Figure 1" :
+For a
+.B 2(n+1)
+processor machine.
+.SH
+The scene
+.PP
+.PS
+.ps 7
+boxwid = 0.5
+boxht = 0.2
+linewid = 0.1
+lineht = 0.2
+box "Scene"
+down; line from last box.s; right; line
+box "Entity"
+down; line from last box.s; right; line
+box "Model"
+down; line from last box.s; right; line
+box "Mesh"
+down; line from last box.s; right; line
+box "Primitive"
+down
+line from 2nd last line.s; line; right; line
+box "Material"
+.ps 10
+.PE
+.SH
+Tile-based rendering
+.PP
+.PS
+.ps 7
+Tiles: [
+ boxht = 0.2
+ boxwid = 1.25
+ down
+ T0: box dashed "tile 0"
+ T1: box dashed "tile 1"
+ Td: box dashed "…"
+ Tn: box dashed "tile n"
+]
+box ht last [].ht+0.1 wid last [].wid+0.1 at last []
+"Screen" rjust with .se at last [].nw - (0.1,0)
+Raster: [
+ moveht = 0.1
+ down
+ R0: circle "rasterizer 0"
+ move
+ R1: circle "rasterizer 1"
+ move
+ Rd: circle "…"
+ move
+ Rn: circle "rasterizer n"
+] with .w at Tiles.e + (0.5,0)
+line from Tiles.T0.e to Raster.R0.w
+line from Tiles.T1.e to Raster.R1.w
+line from Tiles.Td.e to Raster.Rd.w
+line from Tiles.Tn.e to Raster.Rn.w
+.ps 10
+.PE
+.B "Figure 2" :
+Per tile rasterizers.
+.PS
+.ps 7
+Tiles: [
+ boxht = 0.2
+ boxwid = 1.25
+ down
+ T0: box dashed "0"
+ T1: box dashed "1"
+ Td: box dashed "…"
+ Tn: box dashed "n"
+]
+line from last [].w + (0.1,-0.05) to last [].n - (-0.1,0.25)
+line to last [].se - (0.3,-0.1)
+line to 1st line
+box ht last [].ht+0.1 wid last [].wid+0.1 at last []
+"Screen" rjust with .se at last [].nw - (0.1,0)
+Raster: [
+ moveht = 0.1
+ down
+ R0: circle "rasterizer 0"
+ move
+ R1: circle "rasterizer 1"
+ move
+ Rd: circle "…"
+ move
+ Rn: circle "rasterizer n"
+] with .w at Tiles.e + (0.5,0)
+arrow dashed from Tiles.T0.e to Raster.R0.w
+arrow from Tiles.T1.e to Raster.R1.w
+arrow from Tiles.Td.e to Raster.Rd.w
+arrow from Tiles.Tn.e to Raster.Rn.w
+.ps 10
+.PE
+.B "Figure 3" :
+Raster task scheduling.
diff --git a/doc/libgraphics.pdf b/doc/libgraphics.pdf
index 0291710..775d825 100644
--- a/doc/libgraphics.pdf
+++ b/doc/libgraphics.pdf
Binary files differ
diff --git a/doc/libgraphics.ps b/doc/libgraphics.ps
index 1a566f7..081c5d0 100644
--- a/doc/libgraphics.ps
+++ b/doc/libgraphics.ps
@@ -191,7 +191,7 @@
/braceleftbt [203 490]
/bracketrightex [220 -125 500 0]
/radical [0 0 550 0]
- /radicalex [-50 0 500 0]
+ /radicalex [-50 0 500 1]
/parenleftex [-20 -170 0 0]
/integral [100 -50 500 0]
/infinity [10 -75 730 0]
@@ -202,6 +202,82 @@
/endash [7 90 650 0]
] def
%
+% Version 3.3.2 drawing procedures for dpost. Automatically pulled in when
+% needed.
+%
+
+/inpath false def
+/savematrix matrix def
+
+/Dl {
+ inpath
+ {neg lineto pop pop}
+ {newpath neg moveto neg lineto stroke}
+ ifelse
+} bind def
+
+/De {
+ /y1 exch 2 div def
+ /x1 exch 2 div def
+ /savematrix savematrix currentmatrix def
+ neg exch x1 add exch translate
+ x1 y1 scale
+ 0 0 1 0 360
+ inpath
+ {1 0 moveto arc savematrix setmatrix}
+ {newpath arc savematrix setmatrix stroke}
+ ifelse
+} bind def
+
+/Da {
+ /dy2 exch def
+ /dx2 exch def
+ /dy1 exch def
+ /dx1 exch def
+ dy1 add neg exch dx1 add exch
+ dx1 dx1 mul dy1 dy1 mul add sqrt
+ dy1 dx1 neg atan
+ dy2 neg dx2 atan
+ inpath
+ {arc}
+ {newpath arc stroke}
+ ifelse
+} bind def
+
+/DA {
+ /dy2 exch def
+ /dx2 exch def
+ /dy1 exch def
+ /dx1 exch def
+ dy1 add neg exch dx1 add exch
+ dx1 dx1 mul dy1 dy1 mul add sqrt
+ dy1 dx1 neg atan
+ dy2 neg dx2 atan
+ inpath
+ {arcn}
+ {newpath arcn stroke}
+ ifelse
+} bind def
+
+/Ds {
+ /y2 exch def
+ /x2 exch def
+ /y1 exch def
+ /x1 exch def
+ /y0 exch def
+ /x0 exch def
+ x0 5 x1 mul add 6 div
+ y0 5 y1 mul add -6 div
+ x2 5 x1 mul add 6 div
+ y2 5 y1 mul add -6 div
+ x1 x2 add 2 div
+ y1 y2 add -2 div
+ inpath
+ {curveto}
+ {newpath x0 x1 add 2 div y0 y1 add -2 div moveto curveto stroke}
+ ifelse
+} bind def
+%
% Tries to round clipping path dimensions, as stored in array pagebbox, so they
% match one of the known sizes in the papersizes array. Lower left coordinates
% are always set to 0.
@@ -543,41 +619,504 @@ setup
mark
1 pagesetup
12 /LucidaSans-Demi f
-(libgraphics) 2533 1220 w
+(libgraphics) 2533 1230 w
10 /LucidaSans-Italic f
-(Rodrigo G. L\363pez) 2469 1480 w
-(rgl@antares-labs.eu) 2377 1760 w
+(Rodrigo G. L\363pez) 2469 1470 w
+(rgl@antares-labs.eu) 2377 1590 w
+(ABSTRACT) 2626 2030 w
+10 /LucidaSansUnicode00 f
+(To be determined.) 1330 2290 w
+10 /LucidaSans-Demi f
+(Rendering graph) 720 2650 w
+1026 4000 1026 3640 Dl
+1026 3640 1566 3640 Dl
+1566 3640 1566 4000 Dl
+1566 4000 1026 4000 Dl
+7 /LucidaSansUnicode00 f
+(Renderjob) 1123 3834 w
+1566 3820 1926 3820 Dl
+1854 3838 1926 3820 Dl
+1854 3802 1926 3820 Dl
+1926 3820 432 432 De
+(renderer) 1997 3834 w
+2358 3820 2718 3820 Dl
+2646 3838 2718 3820 Dl
+2646 3802 2718 3820 Dl
+2718 3820 432 432 De
+(entityproc) 2763 3834 w
+3510 3064 432 432 De
+(tiler) 3626 3078 w
+(0) 3782 3078 w
+3510 3568 432 432 De
+(tiler) 3626 3582 w
+(1) 3782 3582 w
+3510 4072 432 432 De
+7 /LucidaSansUnicode20 f
+(&) 3691 4086 w
+3510 4576 432 432 De
+7 /LucidaSansUnicode00 f
+(tiler) 3627 4590 w
+(n) 3783 4590 w
+4302 3064 432 432 De
+(rasterizer) 4322 3078 w
+(0) 4670 3078 w
+4302 3568 432 432 De
+(rasterizer) 4322 3582 w
+(1) 4670 3582 w
+4302 4072 432 432 De
+7 /LucidaSansUnicode20 f
+(&) 4483 4086 w
+4302 4576 432 432 De
+7 /LucidaSansUnicode00 f
+(rasterizer) 4323 4590 w
+(n) 4671 4590 w
+3090 3670 3569 3213 Dl
+3530 3275 3569 3213 Dl
+3504 3249 3568 3213 Dl
+3139 3754 3519 3634 Dl
+3456 3672 3519 3634 Dl
+3445 3637 3519 3633 Dl
+3139 3885 3519 4005 Dl
+3445 4002 3519 4006 Dl
+3456 3967 3519 4005 Dl
+3090 3969 3569 4426 Dl
+3504 4390 3568 4426 Dl
+3530 4364 3569 4426 Dl
+3942 3064 4302 3064 Dl
+4230 3082 4302 3064 Dl
+4230 3046 4302 3064 Dl
+3908 3179 4335 3451 Dl
+4265 3428 4335 3451 Dl
+4284 3398 4335 3452 Dl
+3859 3233 4383 3901 Dl
+4325 3856 4383 3901 Dl
+4354 3834 4384 3901 Dl
+3826 3255 4417 4384 Dl
+4368 4329 4417 4384 Dl
+4400 4312 4417 4384 Dl
+3908 3452 4335 3180 Dl
+4284 3233 4335 3179 Dl
+4265 3203 4335 3180 Dl
+3942 3568 4302 3568 Dl
+4230 3586 4302 3568 Dl
+4230 3550 4302 3568 Dl
+3908 3683 4335 3955 Dl
+4265 3932 4335 3955 Dl
+4284 3902 4335 3956 Dl
+3859 3737 4383 4405 Dl
+4325 4360 4383 4405 Dl
+4354 4338 4384 4405 Dl
+10 /LucidaSans-Demi f
+(Figure 1) 720 4990 w
10 /LucidaSansUnicode00 f
-(Antares Telecom Laboratories) 2156 1960 w
-(Albatera, Alicante) 2451 2100 w
+(: For a) 1142 4990 w
10 /LucidaSans-Demi f
-(1.) 720 2700 w
-(Data Structures) 873 2700 w
-(1.1.) 720 2940 w
-(Camera) 962 2940 w
-9 /LucidaTypewriter f
-(struct) 920 3110 w
-(Camera) 1375 3110 w
-({) 1830 3110 w
-(};) 920 3330 w
+(2\(n+1\)) 1481 4990 w
10 /LucidaSansUnicode00 f
-(A camera) 970 3546 w
-8 /S1 f
-(__________________) 720 6980 w
-8 /LucidaSansUnicode00 f
-(ACHTUNG!) 720 7080 w
-(this) 1163 7080 w
-(is) 1333 7080 w
-(a) 1423 7080 w
-8 /LucidaSans-Demi f
-(WORK) 1493 7080 w
-(IN) 1769 7080 w
-(PROGRESS) 1883 7080 w
+(processor machine.) 1843 4990 w
+10 /LucidaSans-Demi f
+(The scene) 720 5230 w
+2196 5572 2196 5428 Dl
+2196 5428 2556 5428 Dl
+2556 5428 2556 5572 Dl
+2556 5572 2196 5572 Dl
+7 /LucidaSansUnicode00 f
+(Scene) 2279 5514 w
+2376 5572 2376 5716 Dl
+2376 5716 2448 5716 Dl
+2448 5788 2448 5644 Dl
+2448 5644 2808 5644 Dl
+2808 5644 2808 5788 Dl
+2808 5788 2448 5788 Dl
+(Entity) 2534 5730 w
+2628 5788 2628 5932 Dl
+2628 5932 2700 5932 Dl
+2700 6004 2700 5860 Dl
+2700 5860 3060 5860 Dl
+3060 5860 3060 6004 Dl
+3060 6004 2700 6004 Dl
+(Model) 2777 5946 w
+2880 6004 2880 6148 Dl
+2880 6148 2952 6148 Dl
+2952 6220 2952 6076 Dl
+2952 6076 3312 6076 Dl
+3312 6076 3312 6220 Dl
+3312 6220 2952 6220 Dl
+(Mesh) 3043 6162 w
+3132 6220 3132 6364 Dl
+3132 6364 3204 6364 Dl
+3204 6436 3204 6292 Dl
+3204 6292 3564 6292 Dl
+3564 6292 3564 6436 Dl
+3564 6436 3204 6436 Dl
+(Primitive) 3237 6378 w
+3132 6364 3132 6508 Dl
+3132 6508 3132 6652 Dl
+3132 6652 3204 6652 Dl
+3204 6724 3204 6580 Dl
+3204 6580 3564 6580 Dl
+3564 6580 3564 6724 Dl
+3564 6724 3204 6724 Dl
+(Material) 3248 6666 w
cleartomark
showpage
saveobj restore
%%EndPage: 1 1
+%%Page: 2 2
+/saveobj save def
+mark
+2 pagesetup
+10 /LucidaSansUnicode00 f
+(\255 2 \255) 2783 480 w
+10 /LucidaSans-Demi f
+(Tile-based rendering) 720 840 w
+2070 1866 2106 1866 Dl
+2142 1866 2178 1866 Dl
+2214 1866 2250 1866 Dl
+2286 1866 2322 1866 Dl
+2358 1866 2394 1866 Dl
+2430 1866 2466 1866 Dl
+2502 1866 2538 1866 Dl
+2574 1866 2610 1866 Dl
+2646 1866 2682 1866 Dl
+2718 1866 2754 1866 Dl
+2790 1866 2826 1866 Dl
+2862 1866 2898 1866 Dl
+2934 1866 2970 1866 Dl
+2970 1866 2970 1830 Dl
+2970 1812 2970 1776 Dl
+2970 1758 2970 1722 Dl
+2970 1722 2934 1722 Dl
+2898 1722 2862 1722 Dl
+2826 1722 2790 1722 Dl
+2754 1722 2718 1722 Dl
+2682 1722 2646 1722 Dl
+2610 1722 2574 1722 Dl
+2538 1722 2502 1722 Dl
+2466 1722 2430 1722 Dl
+2394 1722 2358 1722 Dl
+2322 1722 2286 1722 Dl
+2250 1722 2214 1722 Dl
+2178 1722 2142 1722 Dl
+2106 1722 2070 1722 Dl
+2070 1722 2070 1758 Dl
+2070 1776 2070 1812 Dl
+2070 1830 2070 1866 Dl
+7 /LucidaSansUnicode00 f
+(tile 0) 2435 1808 w
+2070 2010 2106 2010 Dl
+2142 2010 2178 2010 Dl
+2214 2010 2250 2010 Dl
+2286 2010 2322 2010 Dl
+2358 2010 2394 2010 Dl
+2430 2010 2466 2010 Dl
+2502 2010 2538 2010 Dl
+2574 2010 2610 2010 Dl
+2646 2010 2682 2010 Dl
+2718 2010 2754 2010 Dl
+2790 2010 2826 2010 Dl
+2862 2010 2898 2010 Dl
+2934 2010 2970 2010 Dl
+2970 2010 2970 1974 Dl
+2970 1956 2970 1920 Dl
+2970 1902 2970 1866 Dl
+2970 1866 2934 1866 Dl
+2898 1866 2862 1866 Dl
+2826 1866 2790 1866 Dl
+2754 1866 2718 1866 Dl
+2682 1866 2646 1866 Dl
+2610 1866 2574 1866 Dl
+2538 1866 2502 1866 Dl
+2466 1866 2430 1866 Dl
+2394 1866 2358 1866 Dl
+2322 1866 2286 1866 Dl
+2250 1866 2214 1866 Dl
+2178 1866 2142 1866 Dl
+2106 1866 2070 1866 Dl
+2070 1866 2070 1902 Dl
+2070 1920 2070 1956 Dl
+2070 1974 2070 2010 Dl
+(tile 1) 2435 1952 w
+2070 2154 2106 2154 Dl
+2142 2154 2178 2154 Dl
+2214 2154 2250 2154 Dl
+2286 2154 2322 2154 Dl
+2358 2154 2394 2154 Dl
+2430 2154 2466 2154 Dl
+2502 2154 2538 2154 Dl
+2574 2154 2610 2154 Dl
+2646 2154 2682 2154 Dl
+2718 2154 2754 2154 Dl
+2790 2154 2826 2154 Dl
+2862 2154 2898 2154 Dl
+2934 2154 2970 2154 Dl
+2970 2154 2970 2118 Dl
+2970 2100 2970 2064 Dl
+2970 2046 2970 2010 Dl
+2970 2010 2934 2010 Dl
+2898 2010 2862 2010 Dl
+2826 2010 2790 2010 Dl
+2754 2010 2718 2010 Dl
+2682 2010 2646 2010 Dl
+2610 2010 2574 2010 Dl
+2538 2010 2502 2010 Dl
+2466 2010 2430 2010 Dl
+2394 2010 2358 2010 Dl
+2322 2010 2286 2010 Dl
+2250 2010 2214 2010 Dl
+2178 2010 2142 2010 Dl
+2106 2010 2070 2010 Dl
+2070 2010 2070 2046 Dl
+2070 2064 2070 2100 Dl
+2070 2118 2070 2154 Dl
+7 /LucidaSansUnicode20 f
+(&) 2485 2096 w
+2070 2298 2106 2298 Dl
+2142 2298 2178 2298 Dl
+2214 2298 2250 2298 Dl
+2286 2298 2322 2298 Dl
+2358 2298 2394 2298 Dl
+2430 2298 2466 2298 Dl
+2502 2298 2538 2298 Dl
+2574 2298 2610 2298 Dl
+2646 2298 2682 2298 Dl
+2718 2298 2754 2298 Dl
+2790 2298 2826 2298 Dl
+2862 2298 2898 2298 Dl
+2934 2298 2970 2298 Dl
+2970 2298 2970 2262 Dl
+2970 2244 2970 2208 Dl
+2970 2190 2970 2154 Dl
+2970 2154 2934 2154 Dl
+2898 2154 2862 2154 Dl
+2826 2154 2790 2154 Dl
+2754 2154 2718 2154 Dl
+2682 2154 2646 2154 Dl
+2610 2154 2574 2154 Dl
+2538 2154 2502 2154 Dl
+2466 2154 2430 2154 Dl
+2394 2154 2358 2154 Dl
+2322 2154 2286 2154 Dl
+2250 2154 2214 2154 Dl
+2178 2154 2142 2154 Dl
+2106 2154 2070 2154 Dl
+2070 2154 2070 2190 Dl
+2070 2208 2070 2244 Dl
+2070 2262 2070 2298 Dl
+7 /LucidaSansUnicode00 f
+(tile n) 2435 2240 w
+2034 2334 2034 1686 Dl
+2034 1686 3006 1686 Dl
+3006 1686 3006 2334 Dl
+3006 2334 2034 2334 Dl
+(Screen) 1774 1736 w
+3330 1254 432 432 De
+(rasterizer) 3350 1268 w
+(0) 3698 1268 w
+3330 1758 432 432 De
+(rasterizer) 3350 1772 w
+(1) 3698 1772 w
+3330 2262 432 432 De
+7 /LucidaSansUnicode20 f
+(&) 3511 2276 w
+3330 2766 432 432 De
+7 /LucidaSansUnicode00 f
+(rasterizer) 3351 2780 w
+(n) 3699 2780 w
+2970 1794 3330 1254 Dl
+2970 1938 3330 1758 Dl
+2970 2082 3330 2262 Dl
+2970 2226 3330 2766 Dl
+10 /LucidaSans-Demi f
+(Figure 2) 720 3180 w
+10 /LucidaSansUnicode00 f
+(: Per tile rasterizers.) 1142 3180 w
+2070 4170 2106 4170 Dl
+2142 4170 2178 4170 Dl
+2214 4170 2250 4170 Dl
+2286 4170 2322 4170 Dl
+2358 4170 2394 4170 Dl
+2430 4170 2466 4170 Dl
+2502 4170 2538 4170 Dl
+2574 4170 2610 4170 Dl
+2646 4170 2682 4170 Dl
+2718 4170 2754 4170 Dl
+2790 4170 2826 4170 Dl
+2862 4170 2898 4170 Dl
+2934 4170 2970 4170 Dl
+2970 4170 2970 4134 Dl
+2970 4116 2970 4080 Dl
+2970 4062 2970 4026 Dl
+2970 4026 2934 4026 Dl
+2898 4026 2862 4026 Dl
+2826 4026 2790 4026 Dl
+2754 4026 2718 4026 Dl
+2682 4026 2646 4026 Dl
+2610 4026 2574 4026 Dl
+2538 4026 2502 4026 Dl
+2466 4026 2430 4026 Dl
+2394 4026 2358 4026 Dl
+2322 4026 2286 4026 Dl
+2250 4026 2214 4026 Dl
+2178 4026 2142 4026 Dl
+2106 4026 2070 4026 Dl
+2070 4026 2070 4062 Dl
+2070 4080 2070 4116 Dl
+2070 4134 2070 4170 Dl
+7 /LucidaSansUnicode00 f
+(0) 2498 4112 w
+2070 4314 2106 4314 Dl
+2142 4314 2178 4314 Dl
+2214 4314 2250 4314 Dl
+2286 4314 2322 4314 Dl
+2358 4314 2394 4314 Dl
+2430 4314 2466 4314 Dl
+2502 4314 2538 4314 Dl
+2574 4314 2610 4314 Dl
+2646 4314 2682 4314 Dl
+2718 4314 2754 4314 Dl
+2790 4314 2826 4314 Dl
+2862 4314 2898 4314 Dl
+2934 4314 2970 4314 Dl
+2970 4314 2970 4278 Dl
+2970 4260 2970 4224 Dl
+2970 4206 2970 4170 Dl
+2970 4170 2934 4170 Dl
+2898 4170 2862 4170 Dl
+2826 4170 2790 4170 Dl
+2754 4170 2718 4170 Dl
+2682 4170 2646 4170 Dl
+2610 4170 2574 4170 Dl
+2538 4170 2502 4170 Dl
+2466 4170 2430 4170 Dl
+2394 4170 2358 4170 Dl
+2322 4170 2286 4170 Dl
+2250 4170 2214 4170 Dl
+2178 4170 2142 4170 Dl
+2106 4170 2070 4170 Dl
+2070 4170 2070 4206 Dl
+2070 4224 2070 4260 Dl
+2070 4278 2070 4314 Dl
+(1) 2498 4256 w
+2070 4458 2106 4458 Dl
+2142 4458 2178 4458 Dl
+2214 4458 2250 4458 Dl
+2286 4458 2322 4458 Dl
+2358 4458 2394 4458 Dl
+2430 4458 2466 4458 Dl
+2502 4458 2538 4458 Dl
+2574 4458 2610 4458 Dl
+2646 4458 2682 4458 Dl
+2718 4458 2754 4458 Dl
+2790 4458 2826 4458 Dl
+2862 4458 2898 4458 Dl
+2934 4458 2970 4458 Dl
+2970 4458 2970 4422 Dl
+2970 4404 2970 4368 Dl
+2970 4350 2970 4314 Dl
+2970 4314 2934 4314 Dl
+2898 4314 2862 4314 Dl
+2826 4314 2790 4314 Dl
+2754 4314 2718 4314 Dl
+2682 4314 2646 4314 Dl
+2610 4314 2574 4314 Dl
+2538 4314 2502 4314 Dl
+2466 4314 2430 4314 Dl
+2394 4314 2358 4314 Dl
+2322 4314 2286 4314 Dl
+2250 4314 2214 4314 Dl
+2178 4314 2142 4314 Dl
+2106 4314 2070 4314 Dl
+2070 4314 2070 4350 Dl
+2070 4368 2070 4404 Dl
+2070 4422 2070 4458 Dl
+7 /LucidaSansUnicode20 f
+(&) 2485 4400 w
+2070 4602 2106 4602 Dl
+2142 4602 2178 4602 Dl
+2214 4602 2250 4602 Dl
+2286 4602 2322 4602 Dl
+2358 4602 2394 4602 Dl
+2430 4602 2466 4602 Dl
+2502 4602 2538 4602 Dl
+2574 4602 2610 4602 Dl
+2646 4602 2682 4602 Dl
+2718 4602 2754 4602 Dl
+2790 4602 2826 4602 Dl
+2862 4602 2898 4602 Dl
+2934 4602 2970 4602 Dl
+2970 4602 2970 4566 Dl
+2970 4548 2970 4512 Dl
+2970 4494 2970 4458 Dl
+2970 4458 2934 4458 Dl
+2898 4458 2862 4458 Dl
+2826 4458 2790 4458 Dl
+2754 4458 2718 4458 Dl
+2682 4458 2646 4458 Dl
+2610 4458 2574 4458 Dl
+2538 4458 2502 4458 Dl
+2466 4458 2430 4458 Dl
+2394 4458 2358 4458 Dl
+2322 4458 2286 4458 Dl
+2250 4458 2214 4458 Dl
+2178 4458 2142 4458 Dl
+2106 4458 2070 4458 Dl
+2070 4458 2070 4494 Dl
+2070 4512 2070 4548 Dl
+2070 4566 2070 4602 Dl
+7 /LucidaSansUnicode00 f
+(n) 2499 4544 w
+2142 4350 2592 4206 Dl
+2592 4206 2754 4530 Dl
+2754 4530 2142 4350 Dl
+2034 4638 2034 3990 Dl
+2034 3990 3006 3990 Dl
+3006 3990 3006 4638 Dl
+3006 4638 2034 4638 Dl
+(Screen) 1774 4040 w
+3330 3558 432 432 De
+(rasterizer) 3350 3572 w
+(0) 3698 3572 w
+3330 4062 432 432 De
+(rasterizer) 3350 4076 w
+(1) 3698 4076 w
+3330 4566 432 432 De
+7 /LucidaSansUnicode20 f
+(&) 3511 4580 w
+3330 5070 432 432 De
+7 /LucidaSansUnicode00 f
+(rasterizer) 3351 5084 w
+(n) 3699 5084 w
+2970 4098 2990 4068 Dl
+3007 4041 3027 4011 Dl
+3045 3984 3065 3954 Dl
+3083 3928 3103 3898 Dl
+3121 3871 3141 3841 Dl
+3158 3814 3178 3784 Dl
+3196 3758 3216 3728 Dl
+3234 3701 3254 3671 Dl
+3272 3644 3292 3614 Dl
+3309 3588 3329 3558 Dl
+3304 3627 3329 3558 Dl
+3275 3607 3329 3558 Dl
+2970 4242 3330 4062 Dl
+3273 4110 3329 4062 Dl
+3257 4077 3329 4062 Dl
+2970 4386 3330 4566 Dl
+3257 4550 3329 4565 Dl
+3273 4517 3329 4565 Dl
+2970 4530 3330 5070 Dl
+3275 5020 3329 5069 Dl
+3304 5000 3329 5069 Dl
+10 /LucidaSans-Demi f
+(Figure 3) 720 5484 w
+10 /LucidaSansUnicode00 f
+(: Raster task scheduling.) 1142 5484 w
+cleartomark
+showpage
+saveobj restore
+%%EndPage: 2 2
%%Trailer
done
-%%DocumentFonts: S1 LucidaSansUnicode00 LucidaSans-Demi LucidaSans-Italic LucidaTypewriter
-%%Pages: 1
+%%DocumentFonts: LucidaSansUnicode20 LucidaSansUnicode00 LucidaSans-Demi LucidaSans-Italic
+%%Pages: 2
diff --git a/fb.c b/fb.c
index 17496ac..d7a896b 100644
--- a/fb.c
+++ b/fb.c
@@ -13,26 +13,29 @@ framebufctl_draw(Framebufctl *ctl, Image *dst)
{
Framebuf *fb;
- fb = ctl->fb[ctl->idx];
- lock(&ctl->swplk);
+ lock(ctl);
+ fb = ctl->getfb(ctl);
loadimage(dst, rectaddpt(fb->r, dst->r.min), byteaddr(fb->cb, fb->r.min), bytesperline(fb->r, fb->cb->depth)*Dy(fb->r));
- unlock(&ctl->swplk);
+ unlock(ctl);
}
static void
framebufctl_memdraw(Framebufctl *ctl, Memimage *dst)
{
- lock(&ctl->swplk);
- memimagedraw(dst, dst->r, ctl->fb[ctl->idx]->cb, ZP, nil, ZP, SoverD);
- unlock(&ctl->swplk);
+ Framebuf *fb;
+
+ lock(ctl);
+ fb = ctl->getfb(ctl);
+ memimagedraw(dst, dst->r, fb->cb, ZP, nil, ZP, SoverD);
+ unlock(ctl);
}
static void
framebufctl_swap(Framebufctl *ctl)
{
- lock(&ctl->swplk);
+ lock(ctl);
ctl->idx ^= 1;
- unlock(&ctl->swplk);
+ unlock(ctl);
}
static void
@@ -41,11 +44,23 @@ framebufctl_reset(Framebufctl *ctl)
Framebuf *fb;
/* address the back buffer—resetting the front buffer is VERBOTEN */
- fb = ctl->fb[ctl->idx^1];
- memsetd(fb->zbuf, Inf(-1), Dx(fb->r)*Dy(fb->r));
+ fb = ctl->getbb(ctl);
+ memsetd(fb->zb, Inf(-1), Dx(fb->r)*Dy(fb->r));
memfillcolor(fb->cb, DTransparent);
}
+static Framebuf *
+framebufctl_getfb(Framebufctl *ctl)
+{
+ return ctl->fb[ctl->idx]; /* front buffer */
+}
+
+static Framebuf *
+framebufctl_getbb(Framebufctl *ctl)
+{
+ return ctl->fb[ctl->idx^1]; /* back buffer */
+}
+
Framebuf *
mkfb(Rectangle r)
{
@@ -54,8 +69,8 @@ mkfb(Rectangle r)
fb = emalloc(sizeof *fb);
memset(fb, 0, sizeof *fb);
fb->cb = eallocmemimage(r, RGBA32);
- fb->zbuf = emalloc(Dx(r)*Dy(r)*sizeof(*fb->zbuf));
- memsetd(fb->zbuf, Inf(-1), Dx(r)*Dy(r));
+ fb->zb = emalloc(Dx(r)*Dy(r)*sizeof(*fb->zb));
+ memsetd(fb->zb, Inf(-1), Dx(r)*Dy(r));
fb->r = r;
return fb;
}
@@ -63,7 +78,7 @@ mkfb(Rectangle r)
void
rmfb(Framebuf *fb)
{
- free(fb->zbuf);
+ free(fb->zb);
freememimage(fb->cb);
free(fb);
}
@@ -81,6 +96,8 @@ mkfbctl(Rectangle r)
fc->memdraw = framebufctl_memdraw;
fc->swap = framebufctl_swap;
fc->reset = framebufctl_reset;
+ fc->getfb = framebufctl_getfb;
+ fc->getbb = framebufctl_getbb;
return fc;
}
diff --git a/graphics.h b/graphics.h
index fdd1463..5abfa0c 100644
--- a/graphics.h
+++ b/graphics.h
@@ -2,10 +2,16 @@
typedef enum {
ORTHOGRAPHIC,
- PERSPECTIVE
+ PERSPECTIVE,
} Projection;
enum {
+ PPoint,
+ PLine,
+ PTriangle,
+};
+
+enum {
LIGHT_POINT,
LIGHT_DIRECTIONAL,
LIGHT_SPOT,
@@ -21,6 +27,7 @@ typedef struct Vertexattr Vertexattr;
typedef struct Vertex Vertex;
typedef struct LightSource LightSource;
typedef struct Material Material;
+typedef struct Primitive Primitive;
typedef struct Model Model;
typedef struct Entity Entity;
typedef struct Scene Scene;
@@ -29,6 +36,7 @@ typedef struct FSparams FSparams;
typedef struct SUparams SUparams;
typedef struct Shadertab Shadertab;
typedef struct Renderer Renderer;
+typedef struct Rendertime Rendertime;
typedef struct Renderjob Renderjob;
typedef struct Framebuf Framebuf;
typedef struct Framebufctl Framebufctl;
@@ -79,13 +87,12 @@ struct Vertex
Color c; /* shading color */
Point2 uv; /* texture coordinate */
OBJMaterial *mtl;
+
/* TODO it'd be neat to use a dynamic hash table instead */
Vertexattr *attrs; /* attributes (aka varyings) */
ulong nattrs;
};
-typedef Vertex Triangle[3];
-
struct LightSource
{
Point3 p;
@@ -101,16 +108,22 @@ struct Material
double shininess;
};
+struct Primitive
+{
+ int type;
+ Vertex v[3];
+};
+
struct Model
{
- OBJ *obj;
+ Primitive *mesh;
Memimage *tex; /* texture map */
Memimage *nor; /* normals map */
Material *materials;
ulong nmaterials;
- /* cache of renderable elems */
- OBJElem **elems;
+ OBJ *obj;
+ OBJElem **elems; /* cache of renderable elems */
ulong nelems;
};
@@ -118,6 +131,7 @@ struct Entity
{
RFrame3;
Model *mdl;
+
Entity *prev, *next;
};
@@ -128,6 +142,7 @@ struct Scene
ulong nents;
void (*addent)(Scene*, Entity*);
+ void (*delent)(Scene*, Entity*);
};
/* shader params */
@@ -149,12 +164,10 @@ struct FSparams
struct SUparams
{
Framebuf *fb;
- int id;
Memimage *frag;
- Channel *donec;
Renderjob *job;
-
Entity *entity;
+ OBJElem **eb, **ee;
uvlong uni_time;
@@ -174,16 +187,22 @@ struct Renderer
Channel *c;
};
+struct Rendertime
+{
+ uvlong t0, t1;
+};
+
struct Renderjob
{
+ Ref;
Framebuf *fb;
Scene *scene;
Shadertab *shaders;
Channel *donec;
- ulong nrem; /* remaining entities to process */
- ulong lastid;
- uvlong time0;
+ struct {
+ Rendertime R, E, Tn, Rn; /* renderer, entityproc, tilers, rasterizers */
+ } times;
Renderjob *next;
};
@@ -191,21 +210,22 @@ struct Renderjob
struct Framebuf
{
Memimage *cb; /* color buffer */
- double *zbuf; /* z/depth buffer */
- Lock zbuflk;
+ double *zb; /* z/depth buffer */
Rectangle r;
};
struct Framebufctl
{
+ Lock;
Framebuf *fb[2]; /* double buffering */
uint idx; /* front buffer index */
- Lock swplk;
void (*draw)(Framebufctl*, Image*);
void (*memdraw)(Framebufctl*, Memimage*);
void (*swap)(Framebufctl*);
void (*reset)(Framebufctl*);
+ Framebuf *(*getfb)(Framebufctl*);
+ Framebuf *(*getbb)(Framebufctl*);
};
struct Viewport
@@ -215,6 +235,7 @@ struct Viewport
void (*draw)(Viewport*, Image*);
void (*memdraw)(Viewport*, Memimage*);
+ Framebuf *(*getfb)(Viewport*);
};
struct Camera
@@ -234,6 +255,11 @@ struct Camera
uvlong min, avg, max, acc, n, v;
uvlong nframes;
} stats;
+
+ struct {
+ Rendertime R[100], E[100], Tn[100], Rn[100];
+ int cur;
+ } times;
};
/* camera */
@@ -264,6 +290,7 @@ Entity *newentity(Model*);
void delentity(Entity*);
Scene *newscene(char*);
void delscene(Scene*);
+void clearscene(Scene*);
/* vertex */
void addvattr(Vertex*, char*, int, void*);
diff --git a/internal.h b/internal.h
index 7f0d648..213326d 100644
--- a/internal.h
+++ b/internal.h
@@ -1,8 +1,27 @@
-typedef struct Jobqueue Jobqueue;
+typedef struct Tilerparam Tilerparam;
+typedef struct Rasterparam Rasterparam;
+typedef struct Rastertask Rastertask;
-struct Jobqueue
+struct Tilerparam
{
- Renderjob *hd, *tl;
+ int id;
+ Channel *paramsc;
+ Channel **taskchans; /* Channel*[nproc] */
+ Rectangle *wr; /* Rectangle[nproc] */
+ ulong nproc;
+};
+
+struct Rasterparam
+{
+ int id;
+ Channel *taskc;
+};
+
+struct Rastertask
+{
+ SUparams *params;
+ Rectangle wr; /* working rect */
+ Primitive p;
};
/* alloc */
diff --git a/render.c b/render.c
index be19582..8163bc7 100644
--- a/render.c
+++ b/render.c
@@ -42,13 +42,13 @@ isvisible(Point3 p)
}
static int
-isfacingback(Triangle t)
+isfacingback(Primitive p)
{
double sa; /* signed area */
- sa = t[0].p.x * t[1].p.y - t[0].p.y * t[1].p.x +
- t[1].p.x * t[2].p.y - t[1].p.y * t[2].p.x +
- t[2].p.x * t[0].p.y - t[2].p.y * t[0].p.x;
+ sa = p.v[0].p.x * p.v[1].p.y - p.v[0].p.y * p.v[1].p.x +
+ p.v[1].p.x * p.v[2].p.y - p.v[1].p.y * p.v[2].p.x +
+ p.v[2].p.x * p.v[0].p.y - p.v[2].p.y * p.v[0].p.x;
return sa <= 0;
}
@@ -105,7 +105,7 @@ cleanpoly(Polygon *p)
* - https://github.com/aap/librw/blob/14dab85dcae6f3762fb2b1eda4d58d8e67541330/tools/playground/tl_tests.cpp#L522
*/
static int
-cliptriangle(Triangle *t)
+cliptriangle(Primitive *p)
{
/* signed distance from each clipping plane */
static double sdm[6][4] = {
@@ -126,7 +126,7 @@ cliptriangle(Triangle *t)
memset(&Vin, 0, sizeof Vin);
memset(&Vout, 0, sizeof Vout);
for(i = 0; i < 3; i++)
- addvert(&Vin, t[0][i]);
+ addvert(&Vin, p[0].v[i]);
for(j = 0; j < 6 && Vin.n > 0; j++){
for(i = 0; i < Vin.n; i++){
@@ -169,9 +169,9 @@ allin:
* are referenced on every triangle, so duplicate them
* to avoid complications during rasterization.
*/
- t[nt][0] = i < Vout.n-2-1? dupvertex(&Vout.v[0]): Vout.v[0];
- t[nt][1] = Vout.v[i+1];
- t[nt][2] = i < Vout.n-2-1? dupvertex(&Vout.v[i+2]): Vout.v[i+2];
+ p[nt].v[0] = i < Vout.n-2-1? dupvertex(&Vout.v[0]): Vout.v[0];
+ p[nt].v[1] = Vout.v[i+1];
+ p[nt].v[2] = i < Vout.n-2-1? dupvertex(&Vout.v[i+2]): Vout.v[i+2];
}
free(Vout.v);
free(Vin.v);
@@ -292,8 +292,10 @@ orthographic(Matrix3 m, double l, double r, double b, double t, double n, double
}
static void
-rasterize(SUparams *params, Triangle t)
+rasterize(Rastertask *task)
{
+ SUparams *params;
+ Primitive prim;
FSparams fsp;
Triangle2 t₂;
Rectangle bbox;
@@ -302,18 +304,22 @@ rasterize(SUparams *params, Triangle t)
Color c;
double z, depth;
- t₂.p0 = Pt2(t[0].p.x, t[0].p.y, 1);
- t₂.p1 = Pt2(t[1].p.x, t[1].p.y, 1);
- t₂.p2 = Pt2(t[2].p.x, t[2].p.y, 1);
- /* find the triangle's bbox and clip it against the fb */
- bbox = Rect(
- min(min(t₂.p0.x, t₂.p1.x), t₂.p2.x), min(min(t₂.p0.y, t₂.p1.y), t₂.p2.y),
- max(max(t₂.p0.x, t₂.p1.x), t₂.p2.x)+1, max(max(t₂.p0.y, t₂.p1.y), t₂.p2.y)+1
- );
- bbox.min.x = max(bbox.min.x, params->fb->r.min.x);
- bbox.min.y = max(bbox.min.y, params->fb->r.min.y);
- bbox.max.x = min(bbox.max.x, params->fb->r.max.x);
- bbox.max.y = min(bbox.max.y, params->fb->r.max.y);
+ params = task->params;
+ prim = task->p;
+ memmove(prim.v, task->p.v, sizeof prim.v);
+
+ t₂.p0 = Pt2(prim.v[0].p.x, prim.v[0].p.y, 1);
+ t₂.p1 = Pt2(prim.v[1].p.x, prim.v[1].p.y, 1);
+ t₂.p2 = Pt2(prim.v[2].p.x, prim.v[2].p.y, 1);
+ /* find the triangle's bbox and clip it against our wr */
+ bbox.min.x = min(min(t₂.p0.x, t₂.p1.x), t₂.p2.x);
+ bbox.min.y = min(min(t₂.p0.y, t₂.p1.y), t₂.p2.y);
+ bbox.max.x = max(max(t₂.p0.x, t₂.p1.x), t₂.p2.x)+1;
+ bbox.max.y = max(max(t₂.p0.y, t₂.p1.y), t₂.p2.y)+1;
+ bbox.min.x = max(bbox.min.x, task->wr.min.x);
+ bbox.min.y = max(bbox.min.y, task->wr.min.y);
+ bbox.max.x = min(bbox.max.x, task->wr.max.x);
+ bbox.max.y = min(bbox.max.y, task->wr.max.y);
fsp.su = params;
memset(&fsp.v, 0, sizeof fsp.v);
@@ -323,26 +329,22 @@ rasterize(SUparams *params, Triangle t)
if(bc.x < 0 || bc.y < 0 || bc.z < 0)
continue;
- z = fberp(t[0].p.z, t[1].p.z, t[2].p.z, bc);
+ z = fberp(prim.v[0].p.z, prim.v[1].p.z, prim.v[2].p.z, bc);
depth = fclamp(z, 0, 1);
- lock(&params->fb->zbuflk);
- if(depth <= params->fb->zbuf[p.x + p.y*Dx(params->fb->r)]){
- unlock(&params->fb->zbuflk);
+ if(depth <= params->fb->zb[p.x + p.y*Dx(params->fb->r)])
continue;
- }
- params->fb->zbuf[p.x + p.y*Dx(params->fb->r)] = depth;
- unlock(&params->fb->zbuflk);
+ params->fb->zb[p.x + p.y*Dx(params->fb->r)] = depth;
/* interpolate z⁻¹ and get actual z */
- z = fberp(t[0].p.w, t[1].p.w, t[2].p.w, bc);
+ z = fberp(prim.v[0].p.w, prim.v[1].p.w, prim.v[2].p.w, bc);
z = 1.0/(z < 1e-5? 1e-5: z);
/* perspective-correct attribute interpolation */
- bc.x *= t[0].p.w;
- bc.y *= t[1].p.w;
- bc.z *= t[2].p.w;
+ bc.x *= prim.v[0].p.w;
+ bc.y *= prim.v[1].p.w;
+ bc.z *= prim.v[2].p.w;
bc = mulpt3(bc, z);
- berpvertex(&fsp.v, &t[0], &t[1], &t[2], bc);
+ berpvertex(&fsp.v, &prim.v[0], &prim.v[1], &prim.v[2], bc);
fsp.p = p;
c = params->fshader(&fsp);
@@ -354,123 +356,293 @@ rasterize(SUparams *params, Triangle t)
}
static void
-entityproc(void *arg)
+rasterizer(void *arg)
{
- Channel *paramsc;
+ Rasterparam *rp;
+ Rastertask *task;
SUparams *params;
+ Memimage *frag;
+ uvlong t0;
+
+ rp = arg;
+ frag = rgb(DBlack);
+
+ threadsetname("rasterizer %d", rp->id);
+
+ while((task = recvp(rp->taskc)) != nil){
+ t0 = nanosec();
+
+ params = task->params;
+ /* end of job */
+ if(params->entity == nil){
+ if(decref(params->job) < 1){
+ nbsend(params->job->donec, nil);
+ free(params);
+ }
+ free(task);
+ continue;
+ }
+
+ if(params->job->times.Rn.t0 == 0)
+ params->job->times.Rn.t0 = t0;
+
+ params->frag = frag;
+ rasterize(task);
+
+ delvattrs(&task->p.v[0]);
+ delvattrs(&task->p.v[1]);
+ delvattrs(&task->p.v[2]);
+ params->job->times.Rn.t1 = nanosec();
+ free(params);
+ free(task);
+ }
+}
+
+static void
+tilerdurden(void *arg)
+{
+ Tilerparam *tp;
+ SUparams *params, *newparams;
+ Rastertask *task;
VSparams vsp;
OBJVertex *verts, *tverts, *nverts; /* geometric, texture and normals vertices */
OBJIndexArray *idxtab;
- OBJElem **ep, **eb, **ee;
+ OBJElem **ep;
Point3 n; /* surface normal */
- Triangle *t; /* triangles to raster */
- int i, nt;
-
- threadsetname("entityproc");
-
- paramsc = arg;
- t = emalloc(sizeof(*t)*16);
-
- while((params = recvp(paramsc)) != nil){
+ Primitive *p; /* primitives to raster */
+ Rectangle *wr, bbox;
+ Channel **taskchans;
+ ulong Δy, nproc;
+ int i, np;
+ uvlong t0;
+
+ tp = arg;
+ p = emalloc(sizeof(*p)*16);
+ taskchans = tp->taskchans;
+ nproc = tp->nproc;
+ wr = emalloc(nproc*sizeof(Rectangle));
+
+ threadsetname("tilerdurden %d", tp->id);
+
+ while((params = recvp(tp->paramsc)) != nil){
+ t0 = nanosec();
+ if(params->job->times.Tn.t0 == 0)
+ params->job->times.Tn.t0 = t0;
+
+ /* end of job */
+ if(params->entity == nil){
+ if(decref(params->job) < 1){
+ params->job->ref = nproc;
+ for(i = 0; i < nproc; i++){
+ task = emalloc(sizeof *task);
+ memset(task, 0, sizeof *task);
+ task->params = params;
+ sendp(taskchans[i], task);
+ }
+ }
+ continue;
+ }
vsp.su = params;
+ wr[0] = params->fb->r;
+ Δy = Dy(wr[0])/nproc;
+ wr[0].max.y = wr[0].min.y + Δy;
+ for(i = 1; i < nproc; i++)
+ wr[i] = rectaddpt(wr[i-1], Pt(0,Δy));
+ if(wr[nproc-1].max.y < params->fb->r.max.y)
+ wr[nproc-1].max.y = params->fb->r.max.y;
+
verts = params->entity->mdl->obj->vertdata[OBJVGeometric].verts;
tverts = params->entity->mdl->obj->vertdata[OBJVTexture].verts;
nverts = params->entity->mdl->obj->vertdata[OBJVNormal].verts;
- eb = params->entity->mdl->elems;
- ee = eb + params->entity->mdl->nelems;
+ for(ep = params->eb; ep != params->ee; ep++){
+ np = 1; /* start with one. after clipping it might change */
- for(ep = eb; ep != ee; ep++){
- nt = 1; /* start with one. after clipping it might change */
+ /* TODO handle all the primitive types */
idxtab = &(*ep)->indextab[OBJVGeometric];
- t[0][0].p = Pt3(verts[idxtab->indices[0]].x,
- verts[idxtab->indices[0]].y,
- verts[idxtab->indices[0]].z,
- verts[idxtab->indices[0]].w);
- t[0][1].p = Pt3(verts[idxtab->indices[1]].x,
- verts[idxtab->indices[1]].y,
- verts[idxtab->indices[1]].z,
- verts[idxtab->indices[1]].w);
- t[0][2].p = Pt3(verts[idxtab->indices[2]].x,
- verts[idxtab->indices[2]].y,
- verts[idxtab->indices[2]].z,
- verts[idxtab->indices[2]].w);
+ p[0].v[0].p = Pt3(verts[idxtab->indices[0]].x,
+ verts[idxtab->indices[0]].y,
+ verts[idxtab->indices[0]].z,
+ verts[idxtab->indices[0]].w);
+ p[0].v[1].p = Pt3(verts[idxtab->indices[1]].x,
+ verts[idxtab->indices[1]].y,
+ verts[idxtab->indices[1]].z,
+ verts[idxtab->indices[1]].w);
+ p[0].v[2].p = Pt3(verts[idxtab->indices[2]].x,
+ verts[idxtab->indices[2]].y,
+ verts[idxtab->indices[2]].z,
+ verts[idxtab->indices[2]].w);
idxtab = &(*ep)->indextab[OBJVNormal];
if(idxtab->nindex == 3){
- t[0][0].n = Vec3(nverts[idxtab->indices[0]].i,
- nverts[idxtab->indices[0]].j,
- nverts[idxtab->indices[0]].k);
- t[0][0].n = normvec3(t[0][0].n);
- t[0][1].n = Vec3(nverts[idxtab->indices[1]].i,
- nverts[idxtab->indices[1]].j,
- nverts[idxtab->indices[1]].k);
- t[0][1].n = normvec3(t[0][1].n);
- t[0][2].n = Vec3(nverts[idxtab->indices[2]].i,
- nverts[idxtab->indices[2]].j,
- nverts[idxtab->indices[2]].k);
- t[0][2].n = normvec3(t[0][2].n);
+ p[0].v[0].n = Vec3(nverts[idxtab->indices[0]].i,
+ nverts[idxtab->indices[0]].j,
+ nverts[idxtab->indices[0]].k);
+ p[0].v[0].n = normvec3(p[0].v[0].n);
+ p[0].v[1].n = Vec3(nverts[idxtab->indices[1]].i,
+ nverts[idxtab->indices[1]].j,
+ nverts[idxtab->indices[1]].k);
+ p[0].v[1].n = normvec3(p[0].v[1].n);
+ p[0].v[2].n = Vec3(nverts[idxtab->indices[2]].i,
+ nverts[idxtab->indices[2]].j,
+ nverts[idxtab->indices[2]].k);
+ p[0].v[2].n = normvec3(p[0].v[2].n);
}else{
/* TODO build a list of per-vertex normals earlier */
- n = normvec3(crossvec3(subpt3(t[0][1].p, t[0][0].p), subpt3(t[0][2].p, t[0][0].p)));
- t[0][0].n = t[0][1].n = t[0][2].n = n;
+ n = normvec3(crossvec3(subpt3(p[0].v[1].p, p[0].v[0].p), subpt3(p[0].v[2].p, p[0].v[0].p)));
+ p[0].v[0].n = p[0].v[1].n = p[0].v[2].n = n;
}
idxtab = &(*ep)->indextab[OBJVTexture];
if(idxtab->nindex == 3){
- t[0][0].uv = Pt2(tverts[idxtab->indices[0]].u,
- tverts[idxtab->indices[0]].v, 1);
- t[0][1].uv = Pt2(tverts[idxtab->indices[1]].u,
- tverts[idxtab->indices[1]].v, 1);
- t[0][2].uv = Pt2(tverts[idxtab->indices[2]].u,
- tverts[idxtab->indices[2]].v, 1);
+ p[0].v[0].uv = Pt2(tverts[idxtab->indices[0]].u,
+ tverts[idxtab->indices[0]].v, 1);
+ p[0].v[1].uv = Pt2(tverts[idxtab->indices[1]].u,
+ tverts[idxtab->indices[1]].v, 1);
+ p[0].v[2].uv = Pt2(tverts[idxtab->indices[2]].u,
+ tverts[idxtab->indices[2]].v, 1);
}else{
- t[0][0].uv = t[0][1].uv = t[0][2].uv = Vec2(0,0);
+ p[0].v[0].uv = p[0].v[1].uv = p[0].v[2].uv = Vec2(0,0);
}
for(i = 0; i < 3; i++){
- t[0][i].c = Pt3(1,1,1,1);
- t[0][i].mtl = (*ep)->mtl;
- t[0][i].attrs = nil;
- t[0][i].nattrs = 0;
+ p[0].v[i].c = Pt3(1,1,1,1);
+ p[0].v[i].mtl = (*ep)->mtl;
+ p[0].v[i].attrs = nil;
+ p[0].v[i].nattrs = 0;
}
- vsp.v = &t[0][0];
+ vsp.v = &p[0].v[0];
vsp.idx = 0;
- t[0][0].p = params->vshader(&vsp);
- vsp.v = &t[0][1];
+ p[0].v[0].p = params->vshader(&vsp);
+ vsp.v = &p[0].v[1];
vsp.idx = 1;
- t[0][1].p = params->vshader(&vsp);
- vsp.v = &t[0][2];
+ p[0].v[1].p = params->vshader(&vsp);
+ vsp.v = &p[0].v[2];
vsp.idx = 2;
- t[0][2].p = params->vshader(&vsp);
+ p[0].v[2].p = params->vshader(&vsp);
- if(!isvisible(t[0][0].p) || !isvisible(t[0][1].p) || !isvisible(t[0][2].p))
- nt = cliptriangle(t);
+ if(!isvisible(p[0].v[0].p) || !isvisible(p[0].v[1].p) || !isvisible(p[0].v[2].p))
+ np = cliptriangle(p);
- while(nt--){
- t[nt][0].p = clip2ndc(t[nt][0].p);
- t[nt][1].p = clip2ndc(t[nt][1].p);
- t[nt][2].p = clip2ndc(t[nt][2].p);
+ while(np--){
+ p[np].v[0].p = clip2ndc(p[np].v[0].p);
+ p[np].v[1].p = clip2ndc(p[np].v[1].p);
+ p[np].v[2].p = clip2ndc(p[np].v[2].p);
/* culling */
-// if(isfacingback(t[nt]))
+// if(isfacingback(p[np]))
// goto skiptri;
- t[nt][0].p = ndc2viewport(params->fb, t[nt][0].p);
- t[nt][1].p = ndc2viewport(params->fb, t[nt][1].p);
- t[nt][2].p = ndc2viewport(params->fb, t[nt][2].p);
-
- rasterize(params, t[nt]);
+ p[np].v[0].p = ndc2viewport(params->fb, p[np].v[0].p);
+ p[np].v[1].p = ndc2viewport(params->fb, p[np].v[1].p);
+ p[np].v[2].p = ndc2viewport(params->fb, p[np].v[2].p);
+
+ bbox.min.x = min(min(p[np].v[0].p.x, p[np].v[1].p.x), p[np].v[2].p.x);
+ bbox.min.y = min(min(p[np].v[0].p.y, p[np].v[1].p.y), p[np].v[2].p.y);
+ bbox.max.x = max(max(p[np].v[0].p.x, p[np].v[1].p.x), p[np].v[2].p.x)+1;
+ bbox.max.y = max(max(p[np].v[0].p.y, p[np].v[1].p.y), p[np].v[2].p.y)+1;
+
+ for(i = 0; i < nproc; i++)
+ if(rectXrect(bbox,wr[i])){
+ newparams = emalloc(sizeof *newparams);
+ *newparams = *params;
+ task = emalloc(sizeof *task);
+ task->params = newparams;
+ task->wr = wr[i];
+ task->p.v[0] = dupvertex(&p[np].v[0]);
+ task->p.v[1] = dupvertex(&p[np].v[1]);
+ task->p.v[2] = dupvertex(&p[np].v[2]);
+ sendp(taskchans[i], task);
+ }
//skiptri:
- delvattrs(&t[nt][0]);
- delvattrs(&t[nt][1]);
- delvattrs(&t[nt][2]);
+ delvattrs(&p[np].v[0]);
+ delvattrs(&p[np].v[1]);
+ delvattrs(&p[np].v[2]);
}
}
- sendp(params->donec, params);
+ params->job->times.Tn.t1 = nanosec();
+ free(params);
+ }
+}
+
+static void
+entityproc(void *arg)
+{
+ Channel *paramsin, **paramsout, **taskchans;
+ Tilerparam *tp;
+ Rasterparam *rp;
+ SUparams *params, *newparams;
+ OBJElem **eb, **ee;
+ char *nprocs;
+ ulong stride, nelems, nproc, nworkers;
+ int i;
+ uvlong t0;
+
+ threadsetname("entityproc");
+
+ paramsin = arg;
+ nprocs = getenv("NPROC");
+ if(nprocs == nil || (nproc = strtoul(nprocs, nil, 10)) < 2)
+ nproc = 1;
+ else
+ nproc /= 2;
+ free(nprocs);
+
+ paramsout = emalloc(nproc*sizeof(*paramsout));
+ taskchans = emalloc(nproc*sizeof(*taskchans));
+ for(i = 0; i < nproc; i++){
+ paramsout[i] = chancreate(sizeof(SUparams*), 8);
+ tp = emalloc(sizeof *tp);
+ tp->id = i;
+ tp->paramsc = paramsout[i];
+ tp->taskchans = taskchans;
+ tp->nproc = nproc;
+ proccreate(tilerdurden, tp, mainstacksize);
+ }
+ for(i = 0; i < nproc; i++){
+ rp = emalloc(sizeof *rp);
+ rp->id = i;
+ rp->taskc = taskchans[i] = chancreate(sizeof(Rastertask*), 32);
+ proccreate(rasterizer, rp, mainstacksize);
+ }
+
+ while((params = recvp(paramsin)) != nil){
+ t0 = nanosec();
+ if(params->job->times.E.t0 == 0)
+ params->job->times.E.t0 = t0;
+
+ /* end of job */
+ if(params->entity == nil){
+ params->job->ref = nproc;
+ for(i = 0; i < nproc; i++)
+ sendp(paramsout[i], params);
+ continue;
+ }
+
+ eb = params->entity->mdl->elems;
+ nelems = params->entity->mdl->nelems;
+ ee = eb + nelems;
+
+ if(nelems <= nproc){
+ nworkers = nelems;
+ stride = 1;
+ }else{
+ nworkers = nproc;
+ stride = nelems/nproc;
+ }
+
+ for(i = 0; i < nworkers; i++){
+ newparams = emalloc(sizeof *newparams);
+ *newparams = *params;
+ newparams->eb = eb + i*stride;
+ newparams->ee = i == nworkers-1? ee: newparams->eb + stride;
+ sendp(paramsout[i], newparams);
+ }
+ params->job->times.E.t1 = nanosec();
+ free(params);
}
}
@@ -478,83 +650,48 @@ static void
renderer(void *arg)
{
Channel *jobc;
- Jobqueue jobq;
Renderjob *job;
Scene *sc;
Entity *ent;
- SUparams *params, *params2;
- Channel *paramsc, *donec;
+ SUparams *params;
+ Channel *paramsc;
+ uvlong time;
threadsetname("renderer");
jobc = arg;
- jobq.tl = jobq.hd = nil;
- ent = nil;
paramsc = chancreate(sizeof(SUparams*), 8);
- donec = chancreate(sizeof(SUparams*), 0);
proccreate(entityproc, paramsc, mainstacksize);
- enum { JOB, PARM, DONE };
- Alt a[] = {
- [JOB] {jobc, &job, CHANRCV},
- [PARM] {paramsc, &params, CHANNOP},
- [DONE] {donec, &params2, CHANRCV},
- {nil, nil, CHANEND}
- };
- for(;;)
- switch(alt(a)){
- case JOB:
- sc = job->scene;
- job->nrem = sc->nents;
- job->lastid = 0;
- job->time0 = nanosec();
-
- if(jobq.tl == nil){
- jobq.tl = jobq.hd = job;
- ent = sc->ents.next;
- a[PARM].op = CHANSND;
- goto sendparams;
- }else
- jobq.tl = jobq.tl->next = job;
- break;
- case PARM:
-sendparams:
- job = jobq.hd;
- sc = job->scene;
-
- if(ent != nil && ent != &sc->ents){
- params = emalloc(sizeof *params);
- memset(params, 0, sizeof *params);
- params->fb = job->fb;
- params->id = job->lastid++;
- params->frag = rgb(DBlack);
- params->donec = donec;
- params->job = job;
- params->entity = ent;
- params->uni_time = job->time0;
- params->vshader = job->shaders->vshader;
- params->fshader = job->shaders->fshader;
- ent = ent->next;
- }else{
- jobq.hd = job->next;
- if((job = jobq.hd) != nil){
- ent = job->scene->ents.next;
- goto sendparams;
- }
+ while((job = recvp(jobc)) != nil){
+ time = nanosec();
+ job->times.R.t0 = time;
+ sc = job->scene;
+ if(sc->nents < 1){
+ nbsend(job->donec, nil);
+ continue;
+ }
- jobq.tl = jobq.hd;
- a[PARM].op = CHANNOP;
- }
- break;
- case DONE:
- if(--params2->job->nrem < 1)
- send(params2->job->donec, nil);
-
- freememimage(params2->frag);
- free(params2);
- break;
+ for(ent = sc->ents.next; ent != &sc->ents; ent = ent->next){
+ params = emalloc(sizeof *params);
+ memset(params, 0, sizeof *params);
+ params->fb = job->fb;
+ params->job = job;
+ params->entity = ent;
+ params->uni_time = time;
+ params->vshader = job->shaders->vshader;
+ params->fshader = job->shaders->fshader;
+ sendp(paramsc, params);
}
+ /* mark end of job */
+ params = emalloc(sizeof *params);
+ memset(params, 0, sizeof *params);
+ params->job = job;
+ sendp(paramsc, params);
+
+ job->times.R.t1 = nanosec();
+ }
}
Renderer *
diff --git a/scene.c b/scene.c
index 4427835..0984023 100644
--- a/scene.c
+++ b/scene.c
@@ -117,6 +117,16 @@ newmodel(void)
void
delmodel(Model *m)
{
+ if(m == nil)
+ return;
+ if(m->obj != nil)
+ objfree(m->obj);
+ if(m->tex != nil)
+ freememimage(m->tex);
+ if(m->nor != nil)
+ freememimage(m->nor);
+ if(m->nelems > 0)
+ free(m->elems);
free(m);
}
@@ -138,7 +148,10 @@ newentity(Model *m)
void
delentity(Entity *e)
{
- /* TODO free model */
+ if(e == nil)
+ return;
+ if(e->mdl != nil)
+ delmodel(e->mdl);
free(e);
}
@@ -152,6 +165,15 @@ scene_addent(Scene *s, Entity *e)
s->nents++;
}
+static void
+scene_delent(Scene *s, Entity *e)
+{
+ e->prev->next = e->next;
+ e->next->prev = e->prev;
+ e->prev = e->next = nil;
+ s->nents--;
+}
+
Scene *
newscene(char *name)
{
@@ -160,14 +182,30 @@ newscene(char *name)
s = emalloc(sizeof *s);
s->name = name == nil? nil: strdup(name);
s->ents.prev = s->ents.next = &s->ents;
+ s->nents = 0;
s->addent = scene_addent;
+ s->delent = scene_delent;
return s;
}
void
delscene(Scene *s)
{
- /* TODO free ents */
+ if(s == nil)
+ return;
+ clearscene(s);
free(s->name);
free(s);
}
+
+void
+clearscene(Scene *s)
+{
+ Entity *e, *ne;
+
+ for(e = s->ents.next; e != &s->ents; e = ne){
+ ne = e->next;
+ s->delent(s, e);
+ delentity(e);
+ }
+}
diff --git a/util.c b/util.c
index 2a4c7d6..0cd4354 100644
--- a/util.c
+++ b/util.c
@@ -46,7 +46,7 @@ rgb(ulong c)
{
Memimage *i;
- i = eallocmemimage(UR, screen->chan);
+ i = eallocmemimage(UR, RGBA32);
i->flags |= Frepl;
i->clipr = Rect(-1e6, -1e6, 1e6, 1e6);
memfillcolor(i, c);
diff --git a/viewport.c b/viewport.c
index 0e9b9c5..8a18b44 100644
--- a/viewport.c
+++ b/viewport.c
@@ -20,6 +20,12 @@ viewport_memdraw(Viewport *v, Memimage *dst)
v->fbctl->memdraw(v->fbctl, dst);
}
+static Framebuf *
+viewport_getfb(Viewport *v)
+{
+ return v->fbctl->getfb(v->fbctl);
+}
+
Viewport *
mkviewport(Rectangle r)
{
@@ -32,12 +38,15 @@ mkviewport(Rectangle r)
v->fbctl = mkfbctl(r);
v->draw = viewport_draw;
v->memdraw = viewport_memdraw;
+ v->getfb = viewport_getfb;
return v;
}
void
rmviewport(Viewport *v)
{
+ if(v == nil)
+ return;
rmfbctl(v->fbctl);
free(v);
}