Closed osnr closed 10 months ago
I see startup errors on virtual-programs/shapes.folk:
Error in virtual-programs/shapes.folk, match m89:0: wrong # args: should be "apply lambdaExpr this shapes p a shape options"
wrong # args: should be "apply lambdaExpr this shapes p a shape options"
while executing
"apply $lambda {*}$env"
invoked from within
"time {set ret [apply $lambda {*}$env]}"
("uplevel" body line 1)
invoked from within
"uplevel [list time $body]"
(procedure "baretime" line 1)
invoked from within
"baretime {set ret [apply $lambda {*}$env]}"
(procedure "runInSerializedEnvironment" line 9)
invoked from within
"runInSerializedEnvironment $lambda $env"
Is shapes.folk supposed to work with the new approach?
I see startup errors on virtual-programs/shapes.folk:
Error in virtual-programs/shapes.folk, match m89:0: wrong # args: should be "apply lambdaExpr this shapes p a shape options" wrong # args: should be "apply lambdaExpr this shapes p a shape options" while executing "apply $lambda {*}$env" invoked from within "time {set ret [apply $lambda {*}$env]}" ("uplevel" body line 1) invoked from within "uplevel [list time $body]" (procedure "baretime" line 1) invoked from within "baretime {set ret [apply $lambda {*}$env]}" (procedure "runInSerializedEnvironment" line 9) invoked from within "runInSerializedEnvironment $lambda $env"
Is shapes.folk supposed to work with the new approach?
Yes -- I think that's an overzealous match where shapes and sprites collide, it should be ignorable (but we should fix it)
This is great! It was pretty easy to port my current set of interesting programs
Open questions / notes (will update this over time):
Start process
without a name, Start process { ... }
if you don't want to deploy code to it latervert
, frag
, fn
, etc, rather than just having like 4 positional arguments in a literal? Should it look more like C where there's a compiler object that you build up?
Wish to draw
should be Wish the display draws
-- you can think of there being levels of abstraction Wish $this draws
(object-centric) > Wish the display draws
(natural-language wish) > Wish the GPU draws pipeline
(GPU-arglist / shader wish) > Gpu::draw
(Tcl imperative) > Gpu::drawImpl
(C) > vkCmdDraw
(Vulkan/GPU driver)Things to do:
I'm partial to the Wish to draw
syntax as being a bit agnostic to what is doing the drawing. I feel like most folk drawing should be done composed as drawing programs (which would then make it easy to federate?)
I'm going to punt on some of the user-facing shader language stuff until next PR (including resource management questions). The main remaining thing is performance (currently 45-55fps instead of a solid 60).
The bottleneck is the glyph / text shaping loop in display/text.folk (you can see for yourself by returning before the actual GPU render wish -- it's just as slow -- and then returning before the whole loop -- performance gets way better). 'Easy' solution is to rewrite in C. Will think about it tomorrow.
Performance is now comparable (within 5fps better/worse depending on context) to main for me, so I'll merge it.
The display primitives (text, triangles, circles, lines, polygons) are now in separate programs in virtual-programs/display/, which is easier to read and patch and more idiomatic.
(Virtual programs can now live in subfolders like /display/ and will be picked up by the system, other than the _archive subfolder.)
They all use wishes as their interface; all Display:: calls have been deprecated and produce a visible warning above any program that uses them. The new wishes generally have optional parameters (color, fill, radians, etc).
Examples from shapes.folk:
(Arcs and shapes and sprites and fonts have all been ported to the new way of doing things.)
dict_getdef
has been added, which is used pervasively through the new display wishes, along with rest patterns from #94, to implement those optional parameters.Subprocess code deployment has changed. You boot a subprocess now with
Start process NAME
, like:You can send more code to an already-existing subprocess with
On process NAME
:This is used to deploy code from individual programs to the GPU process without it all having to be in one monolithic file anymore.
There are some catches / ugly bits: process names are global & you now have to explicitly opt into all sharing (either share or receive); there's no sharing by default anymore.
You can now write arbitrary shaders from programs. There aren't great helpers for this yet, like shading a region or anything like that, so you need to work in projector coordinates by hand for now. Let me know what you think would be useful to have.
Here is a very basic and not very useful shader that you can just paste as a virtual program (or print). It will color a triangle underneath itself green-blue.
See https://github.com/FolkComputer/folk/pull/93 for more info about the shader source object that you pass to the pipeline compilation wish. Also see the implementations of drawing primitives in virtual-programs/display/*.folk.
Notice how you compile the pipeline once (when the program is put down), and then it gets executed repeatedly (whenever the program's region changes).
I'm noticing a moderate performance regression here, where this branch hovers between 50-55fps instead of being solidly at 60fps; the evaluator on the display subprocess seems to be much slower (10-12ms per frame) now. Would like to fix this before merging... let me know how much of a problem it is for you.