<mark_weaver>unknown_lamer: I'm just now reading the backlog. I can tell you definitively, as the defacto maintainer of the numerics code in guile in recent years, that floats in Guile are *always* allocated on the heap. <unknown_lamer>I thought constant floats at least were put into the program's object vector ? <mark_weaver>in the stack VM, constant floats are stored as strings (yes, strings), and converted to heap-allocated floats when the module is loaded. <mark_weaver>in the RTL VM, it's *possible* that constant floats are statically allocated; I'm not sure. <mark_weaver>but in any case, any non-compile-time-constant float is heap-allocated, even in the RTL VM. <ijp>storing them as strings is why we needed to fix string->number way back when <mark_weaver>which means that there's no way to do any kind of math and stuff it into a homogeneous vector without allocating the numbers in the stack. <ijp>apparently I've decided to wake up at 3am today <mark_weaver>ijp: well, it's not the only reason we needed to, but it certainly made the problem much worse. <mark_weaver>I messed up my second-to-last line. it should end with "without allocating the floats in the heap before they are stored." <mark_weaver>I have a patch that implements NaN-boxing for the master branch. However, it has various problems that make me reluctant to make it the standard tagging scheme. <ijp>why didn't we store them as actual numbers, portability reasons? <unknown_lamer>does this mean that using uvecs for math is actually... not sensible <mark_weaver>well, it's still much more efficient for compact storage. <unknown_lamer>since there are no vector operations, and ufNNvector-ref ends up having to allocate a boxed float? <davexunit>unknown_lamer: it's probably the best way to do it, but you're still generating garbage. <mark_weaver>ijp: I don't know; I wasn't around when that decision was made. wingo wrote that code. <davexunit>which is why you see figl's particle demo constantly collecting garbage. *unknown_lamer is implementing the uniform setting interface in gl now <davexunit>thank you mark_weaver for explaing this all again. <ijp>I've come to appreciate that these decisions are usually made for reasonable decision, but it still seems a little weird to me <mark_weaver>however, the good news is that we should be able to enhance the compiler to deduce in some cases that a given value is always a float, and thus unbox the float. <ijp>mark_weaver: yeah, I wasn't around either. we'll see if I remember to ask him.... <davexunit>unknown_lamer: you can get away with integers to an extent, opengl programs work with floats primarily so at some point you will have to pay the price. <mark_weaver>in some cases, the compiler may be able to deduce this without any help, but in other cases it can be helped along by using the R6RS flonum operations. <davexunit>mark_weaver: someone once told me that using the r6rs flonum operations was how people programming racket did efficient floating point math. <mark_weaver>I also wrote another patch that made floats immediate by reducing the precision by 3 bits. <mark_weaver>but that was a can of worms for various other reasons. <davexunit>yeah, too high a price for immediate floats. <mark_weaver>unknown_lamer: currently, SCM values are always the same size as pointers. <mark_weaver>fixnums are 2 bits less than that, so 30 bits on 32-bit platforms and 62 bits on 64-bit platforms. <unknown_lamer>why not ... if (sizeof '*) -> 8, just use all of that beautiful space... <mark_weaver>(the low bit is always 0 for any SCM value, and the next-to-lowest bit indicates whether it's a fixnum or not) <unknown_lamer>otherwise, sorry, 32-bit platforms are for heap allocating lamers <mark_weaver>unknown_lamer: well, okay, but doubles are 64-bits, which leaves no space for the tag. <mark_weaver>NaN-boxing is a well-known trick, used by some javascript implementations in web browsers, where everything that's not a float is represented by a NaN. <ijp>why does floating point have so many NaNs? <mark_weaver>(possibly with the entire 64-bit ring rotated to make pointers remain unchanged) <unknown_lamer>since opengl uses those almost exclusively (well, entirely until 4.x) <mark_weaver>ijp: well, for implementation reasons, it makes sense to detect NaNs by a given pattern in the exponent field, leaving hte entire significand free for other stuff. <mark_weaver>in IEEE, when the exponent is the maximum value, then it's infinity if the significand is all zeroes, otherwise it's a NaN. <mark_weaver>trying to make fewer NaNs would have made the implementation for difficult. <mark_weaver>unknown_lamer: sure, single floats are still useful, that's true. but that opens a whole other can of worms in a dynamically typed system. <mark_weaver>and it would make more cases to consider in every generic math operation. <mark_weaver>the number of cases that every generic math operation has to implement is N^2 where N is the number of representations. <mark_weaver>and you can get away with fewer cases only by making them considerably slower. ***fangism is now known as fangism-ctrl-Z
<mark_weaver>anyway, with the R6RS flonum operations, it will be quite feasible to avoid boxing floats in many cases, and fairly easy to write code that can depend on this fast. <mark_weaver>well, CL also allows explicit type annotations, which helps a lot. <ijp>I hate the term "inferencer" <mark_weaver>the nice thing about the R6RS flonum ops is that their results are guaranteed to be flonums, which is very helpful for type inference. <mark_weaver>and they can also heavily optimize the case where the inputs are all flonums, because they raise an exception in any other case. <mark_weaver>still, in the meantime, I'm thinking that I should get my nan-boxing patch updated and let davexunit use it in the meantime, so that he'll get some idea of what performance will be like with unboxed floats. <mark_weaver>(and we could certainly make it a compile-time option; the patch isn't very big) <mark_weaver>(sadly, it's not feasible to make it a run-time option) <mark_weaver>I've been focused on Guix lately, getting the MIPS/Loongson port up and running, but I intend to come back to Guile land to get a bunch of things into master before 2.2 is released. <b4283>unknown_lamer: i remember you asked something generating code in one thread and running the code in another <b4283>may i ask what is the purpose of this design? <unknown_lamer>b4283: run GLUT/OpenGL in a thread, and then use the repl to ship code off to the gl thread <unknown_lamer>mark_weaver: why not stop storing tag bits in SCM and store them separately *unknown_lamer waits for someone else to rewrite guile to do this <mark_weaver>unknown_lamer: I've often considered that idea, but where would you store them? <mark_weaver>unfortunately, it makes moving SCM values around more expensive, in terms of both code size and CPU cycles. <mark_weaver>and I don't see how it could be done without drastically changing our C API. <mark_weaver>nalaginrut: right, now that I use only YeeLoongs, I need Guix to work on them :) <nalaginrut>IIRC, modern needs dynamic-compilation, so sounds very cool to try~ <mark_weaver>djbclark very kindly lent me his much-faster Loongson 3A-based YeeLoong 8133. It's quite competitive. <mark_weaver>(unfortunately it requires a blob for the Radeon video chip) <nalaginrut>but last time when I tried guix, it can't work on my laptop <mark_weaver>nalaginrut: did you talk to us about it? It should work on any intel-based or 64-bit MIPS-based machine now. <mark_weaver>(though for MIPS you need to use a special branch in git for now) <nalaginrut>I talked to ludo, but seems he's busy at that time <mark_weaver>(MIPS will be fully supported in the next release: Guix 0.5) <nalaginrut>I wonder if there's much work to do for Guix porting, since I thought it's a pure userland thing <nalaginrut>I mean there shouldn't be any platform specified code to be modified for porting, no? <mark_weaver>the main things Guix needs now are (1) more package build recipes added, especially for modern desktop environments, and (2) make it usable as a standalone distro. <nalaginrut>or maybe you're doing cross-compiling config for it? <mark_weaver>well, in theory there's not much to be done for porting, but in practice there tend to be things that need to be patched up for the less popular platforms. <mark_weaver>but packing for Guix also typically involves fixing problems in the package build systems that assume the standard filesystem layout. *nalaginrut guix refreshing... <nalaginrut>is there any different between rpm and deb based distros, for guix? <mark_weaver>not really. The software installed in Guix is completely self-contained; it makes use of *nothing* from the outer system except for the kernel, /dev, and a few other things like that. in particular, it includes it's own C library, dynamic linker, etc. everything lives in /nix/store/* <mark_weaver>and the software is all built in such a way that it looks for its dependencies in /nix/store/*. <mark_weaver>However, in order to install Guix, you need to first compile the guix package manager itself, and that gets linked with your platform libraries. <nalaginrut>besides, any multi-thread supported added to guix? <mark_weaver>Guix sticks very close to the most recently released upstream tarballs of each package. <mark_weaver>with pretty much the minimal patches needed to make things work. <mark_weaver>I don't know what you have in mind by "any multi-thread supported added to guix?" <nalaginrut>guix build: error: build failed: setting synchronous mode: unable to open database file <mark_weaver>in practice, on intel platforms, you can download pre-built binaries from hydra.gnu.org if you use the standard guix package recipes. <ZC|Mobile>can anyone see a problem with putting guile into an initramfs and using it for the init file? <mark_weaver>ZC|Mobile: it should be doable. have you heard of boot-to-guile? <mark_weaver>ZC|Mobile: also take a look at 'dmd', which is an init program based on Guile. <mark_weaver>after some years of inactivity, it is now seeing new development because it will be the default init program for GNU Guix, when it's a standalone distro. <ZC|Mobile>well, that isn't quite what I need. I'm in the process of migrating my initramfs from supporting one system to supporting two in some fairly diffrent enviroments, and want something a little saner to work with than busybox sh <ijp>systemd isn't that bad <unknown_lamer>systemd is just ... hey, you guys probably mocked dmd years ago and now look at what you've gone and done <unknown_lamer>sysvinit is baaad because it uses programs. systemd is good because it requires you to implement new functionality in C and have it included by the gatekeepers and slowly trickle downstream over the course of two years <ZC|Mobile>systemd's use of cgroups is nice. That is about all I can say about it. <ijp>it's *really* hard to get me to sympathise with any argument which involves not getting rid of shell <mark_weaver>ZC|Mobile: okay, well, it can certainly be done, but beware that init programs are expected to do some initialization tasks, and to run setsid before running programs, etc. I don't know all the details. It can certainly be done in Guile, and *is* being done in Guile with the GNU Guix initrds, but it's not exactly something that works easily "out of the box". <mark_weaver>re: systemd, I'm glad to see all the shell scripts die, but I want them to be scheme instead. i don't want to have to recompile a C program to make little changes to how initialization happens. <ZC|Mobile>I just want something other than sh to handle logic and configuration. I have no issues with calling system bins <mark_weaver>and I *really* don't like that they are tying themselves to linux exclusively, and leaving other kernels in the cold. <mark_weaver>ZC|Mobile: okay, well, if you're willing to fiddle, it can certainly be done. <ZC|Mobile>mark_weaver: better than using scheme for initscripts would be to open the system up to being able to run the scripts as something of a standalone binary or whatever. Let the user pick their poison/language <ZC|Mobile>but that is just my view on that little matter <ijp>ZC|Mobile: i.e. you want things to remain the way they are <ZC|Mobile>ijp: I'm all for improving init, but any choice regarding the initscript language is going to run into issues of one nature or another <ijp>why should initscripts be able to run anything and everything? <ZC|Mobile>Proponents of one language or another will get annoyed, and having to learn yet another config language is annoying <ZC|Mobile>ijp: I'd imagine some people could use such control in some edge case enviroments <ijp>yeah, but you signed up for that when you ran unix <mark_weaver>anyway, I don't actually want something like the existing scripts, but simply translated into scheme. <mark_weaver>I want most of that code to simply go away. it's mostly boilerplate anyway, with huge amounts of redundancy. <ijp>that's why they moved to those .ini style config files <mark_weaver>scheme has the flexibility to create nice domain-specific languages to handle the common cases nicely. <mark_weaver>but I want to be able to do more arbitrary stuff when needed, without recompiling or restarting init. <mark_weaver>there's a lot about systemd that I admire, but I'd rather reimplement those ideas in something like dmd. <mark_weaver>for another thing, I don't want to leave Hurd and other kernels out in the cold. <ijp>I can see it both ways <ijp>there is a catch-22 in standards, and posix in particular isn't exactly a diamond <ijp>the attitude is more worrying than the reality <mark_weaver>I'll acknowledge that there are advantages to focus on a single kernel, I'm not ready to do that for Linux. I, for one, find the Hurd quite compelling. I'd like to run it some day. <mark_weaver>and it has seen something of a resurgence in recent years. <mark_weaver>hmm. guile master assumes that the kernel page size is 4K, but linux allows 16K and 64K page sizes. mine is configured for 16K, so guile master doesn't work. <mark_weaver>hmm. my first thought, for a hack to get this working, was to change the definition of SCM_PAGE_SIZE in objcodes.c to 16384. but now I see that SCM_PAGE_SIZE is used in only one place, and it's *above* the place where it's #defined. <mark_weaver>but I also see a hardcoded 4096 in objcodes.c that's more likely the thing to change. <mark_weaver>but I don't see how this can work. so it changes the perms to allow write access, but only if the alignment is 4096. otherwise it just leaves it read-only. <mark_weaver>I'll need to talk to wingo about what's going on here. <mark_weaver>damn. I hope it's not too hard to fix this. the page size cannot be a compile-time constant. <mark_weaver>hopefully wingo didn't assume that it was a compile-time constant in the design of this thing. *nalaginrut is watching ludo's guix video on GHM <mark_weaver>what distro are you using that doesn't support vorbis? <mark_weaver>that's one of the few codecs that any distro should be able to support by default without patent concerns. <mark_weaver>nalaginrut: yes, "getconf PAGESIZE" is the way I know to find that out (not sure what it does under the hood). <mark_weaver>wow, opensuse doesn't support vorbis. that's terrible. <mark_weaver>nalaginrut: no, that doesn't work, because the kernel can be changed without recompiling userland. <mark_weaver>what concerns me is that the page size (currently assumed to be 4K) seems to be baked into the ELF files somehow. <nalaginrut>how about record the kernel-img mtime, and regenerate the pagesize one the fly if mtime changed (sounds not so cool) <mark_weaver>well, best not to make any assumptions until I talk to wingo. <mark_weaver>I don't think it's good if all .go files have to be recompiled when you change kernels. *nalaginrut is finding a way for vorbis under openSUSE... <nalaginrut>mark_weaver: I think so, since pagesize should be un-relative to exec format <nalaginrut>actually I want to change distro to debian/Hurd, but it still needs some work... <unknown_lamer>;;; 121 frames in 2.01 sec = 60.05 fps; 16.65 ms/frame, 26.23 ms max; 20.07% CPU; 0 GC <unknown_lamer>it still gcs and stall for an extra 15ms occasionally, but not every five second period <nalaginrut>mark_weaver: when I changed the backend from mplayer2 to mplayer, it's OK now <nalaginrut>anyway, now I know how to pronounce ludo's name ;-D <nalaginrut>"The truth is that Lisp is not the right language for any particular problem. Rather, Lisp encourages one to attack a new problem by implementing new language tailored to that problem" haha <madsy>Lisp isn't a language. It's a programmable and highly customizable compiler <ijp>lisp isn't a language, it's a religion <madsy>ijp: If it is a religion, what is worshipped? <madsy>Hm. I don't know about anyone who worships any language :) <ijp>visit your university's latin department <nalaginrut>well, actually we don't use Lisp, some smart guys implemented Scheme to solve our problems: to implement a language which is more suitable to implement a language <nalaginrut>zacts: I tried it, it works, although sometimes it halt *mark_weaver prefers R6RS <ijp>talk to me in two years when there are six implementations so I can call it a failure <unknown_lamer>so now they can go into guile instead of into some util library no one else will find <mark_weaver>R6RS has a much better bytevector library than R7RS. <ijp>because I'm willing to be you $5 we have support for them in guile right now <mark_weaver>(guile already supports the far-superior R6RS bytevector library) <unknown_lamer>ijp: bytevector-copy/utf8->string with start/end arguments, bytevector-append mostly <unknown_lamer>you *can* implement them all on top of bytevector-copy!, which is probably why the r6rs editors left them out <unknown_lamer>at the same time why even bother having bytevector-copy at that point <ijp>I haven't really found bytevector-append to be that useful in practice <ijp>and I can't really see it for utf8->string <ijp>I'll grant you the other <ijp>yes, but we've known that for 20 years <unknown_lamer>for utf8->string it'd be great because opengl at least refuses to not return the trailing null <ijp>christ, it really is almost as old as I am <ijp>I used to want a (bytevector) function <TaylanUB>What about the new, "object-oriented" API ? :P (I suppose they're also 20 years too late, trying to follow that trend ...) <ijp>what object-oriented API? <unknown_lamer>it's less object oriented and more here, gpus work like this now so you have to too <unknown_lamer>also the whole opengl 3.3 ditches enough that you have to contort yourself to write programs that work with 2.1 and 3.3+ <ijp>I remember abstraction, it was all the rage in the 90s <TaylanUB>Oh wait, it must be that I misinterpreted something I read a while ago, can't find anything about OO anymore ... <unknown_lamer>which are just chunks of memory you send over to the gpu and then tell it how to interpret <unknown_lamer>instead of doing things like glDrawVertex4f (...) you load up an array and go <ijp>actually, I already have the restricted bytevector copy in my (ijputils bytevectors) under the name subbytevector <ijp>no idea why I didn't stick a hyphen in there <dsmith>If the page size is an assumed constant for ELF files in general, how would any exec or .so be able at runtime to call sysconf to detect the page size? ***gjanssens-afk is now known as gjanssens
*nalaginrut fixed '(a b . c) bug in guile-colorized finally... <madsy>nalaginrut: Just a display bug? <madsy>As '(a b . c) and '(a . b c) are the same right? <ijp>the latter is not even meaningful <madsy>Isn't '(a b . c) just a list containing a symbol and a cons cell? <nalaginrut>madsy: for guile-colorized, it's just a display bug <nalaginrut>the bug is '(a b . c) ==> (a . (b . c)), which appears when you enabled colorized <madsy>Bleh.. I'm fighting cmake to build my docs <nalaginrut>I updated master of guile-colorized, so it never support Guile1, I think it's better to push new users try Guile-2.0.9 <gjanssens>wingo: you mentioned yesterday that there are two backtrace printers <wingo>there is no other option in 1.8, fwiw <sneek>Welcome back wingo, you have 1 message. <gjanssens>I can conditionally use the other option in 2.0 <wingo>gjanssens: the other option is to use call-with-error-handling; search the manual for that <dsmith-work>wingo: Mark is using a non-4k page size on the guix YeeLoong <wingo>i just don't like the "concerned guile citizen" tone <wingo>of course pages are crucial to a linker doing its job <wingo>the question is how to get pages to work properly in all cases, and a per-target page size sounds reasonable to me <dsmith-work>I can't see how the page size can be discoverable at runtime if the binary file depends on it. <wingo>right, that is a bogus design <wingo>we could fall back on the malloc path but that is a terrible option <wingo>platforms have abis for this reason. <dsmith-work>Maybe if the arch has a variable page size, the file needs to be layed out with the max alignment. <wingo>that has obvious negative repercussions for systems with the default page size, but perhaps that doesn't matter <wingo>i wonder what the gnu linker does in this case <wingo>it seems that the x86-64 abi also allows for a variable page size (4 to 64 kB, must be a power of 2) <gjanssens>(catch #t (lambda () (lazy-catch #t eval-input pre-unwind-handler)) error-handler)) <gjanssens>(catch #t eval-input error-handler pre-unwind-handler)) <wingo>well that's good anyway, lazy-catch has been deprecated for a long time now <gjanssens>the lazy-catch construct was there for compatibility with guile 1.6 according to the comments <wingo>well i'm sorry i couldn't be of more assistance <wingo>but i'm glad you found the thing :) <gjanssens>oh your input did help. I wouldn't know what to look for without your remarks <madsy>Finally I can build the docstrings and my binary at the same time <wingo>gjanssens: thank you for getting gnucash to work with guile 2.0. don't hesitate to come and ask again if you need help :) <wingo>we might be as worthless as we were in this case, but hopefully not :) <gjanssens>wingo: hunting down this bug brought up several unrelated questions, which I'll come back to later when I revisit the relevant areas in gnucash <gjanssens>I found gnucash using 'scm_internal_stack_catch' <gjanssens>The suggested replacement is 'call-with-error-handling' <wingo>humm, and news doesn't mention its deprecation; shame on us <gjanssens>The former is a c function, but the latter a guile function <wingo>so to use a C function -- does gnucash call into guile from multiple threads? <wingo>the manual has an example in 6.20.9 Accessing Modules from C <wingo>you use scm_c_public_lookup, store the result in a static SCM, then use scm_call_1 (scm_variable_ref (call_with_error_handling_var), my_proc) <wingo>or the appropriate scm_call_n variant if you pass additional args *gjanssens has just finished reading the documentation on call-with-error-handling <gjanssens>what's not clear to me: does this function print a backtrace by default ? <gjanssens>Or do I have to fiddle with on-error and post-error custom functions to get that ? <wingo>hah, no -- you have to pass #:on-error 'debug <wingo>i think that option is undocumented! <wingo>also do #:post-error 'report <wingo>you can pass functions there but it's easier to pass those symbols to indicate that you want the built-in behavior *wingo checks that 'backtrace is a thing; i think it is <wingo>sometimes what you want is some kind of #:on-error (if debug-mode? 'debug 'backtrace) <wingo>for a suitable definition of debug-mode? <wingo>it's not something you want to ship to users but it is really nice when developing to get a repl in the context of the error <gjanssens>what would happen if this was set up inside gnucash ? <gjanssens>gnucash is a c application that starts a guile environment via scm_boot_guile <wingo>that would probably spawn a repl on the console <wingo>you can get a repl in a window but that's a lot harder actually *wingo rewrites the rtl slot allocator, whee <wingo>i hope to get call arg allocation to be more sensible <wingo>okeydoke, so we should change to use the maximum size afaics ***sneek_ is now known as sneek
*stis thinks that logic-programs needs 2 modes of compilation. <stis>1. Targetting native compilation <stis>2 can be a magnitude faster to compile, 1 can be marginally (2x <) faster on native platform <stis>I could probably make a much faster match routine then ice-9 match, with the same interface for RTL and stack vm <wingo>lloda: i didnt' get to your thing today, as i forgot to pull mail before going to the cafe <tupi>wingo: good night! no news from mark so far, maybe he is working on it [(ice-9 popen)] thread safe problem], i don't know, do you ? <tupi>ok, i am concerned, as i said yesterday, and you suggested i ping you if no news tonight so i am pinging you :) <wingo>i don't have time unfortunately <wingo>not today or tomorrow anyway :/ ***fangism-ctrl-Z is now known as fangism
<tupi>are you sure? i'll get you a very very good wine :) <tupi>hello mark_weaver! how nice you are there :) <mark_weaver>sorry to make you concerned. first of all, I've long known a hacky way to "fix" the problem that assumes that all pipes will be closed explicitly. <mark_weaver>however, the better news is that, after some long mulling it over, I think I know how to fix the problem more properly. <tupi>that is good news indeed! <mark_weaver>I know it's a bit last-minute, but I will have a patch for you in the next day or two. <tupi>that's ok, if i get it before monday, i'll compile here and have a way to send a compiled version to 'them', install with my instrcutions and try the patch. if tuesday, i'll take it with me and ... <unknown_lamer>davexunit: there are two undocumented procedures: gc-enable and gc-disable <mark_weaver>tupi: btw, although it is not related to this (ice-9 popen) problem, I also strongly recommend that you make sure libgc-7.2d is being used on their system. <tupi>once i am there though, i don't have access to internet [they are trying to solve that problem], so it could be that i try, then send an email at night while at my hotel ... <unknown_lamer>davexunit: by disabling gc around the disable and re-enabling it immediately after (swap-buffers) I got the average frame time down to 13ms <tupi>mark_weaver: i will check, is it very recent ? <unknown_lamer>however, then the gc ends up stalling for longer occasionally... <unknown_lamer>I also was able to get gc out of the picture mostly by reducing the particle count <mark_weaver>tupi: no, it's been out for quite a long time, but Debian stable has a much older version which has various problems. <tupi>there are on debian testing like me, but i dont remember what version they run, I will send an email <unknown_lamer>still, even when not doing gc runs, something was causing frames to stutter a bit <davexunit>unknown_lamer: could be what's known as "temporal aliasing" <mark_weaver>tupi: jessie (testing) has 7.2d, which is good. debian stable (wheezy) has 7.1, which is not so good. <tupi>they should have mine, i have libgc1c2:amd64 <davexunit>stutter can happen is updating and rendering are not in lock step with each toerh. <tupi>mark_weaver: i received the autho to pay you for this patch, at some point we'll talk on how to do that ... <unknown_lamer>the particle demo also assumes time is 1/60th of a second too <tupi>mark_weaver: many thanks again <unknown_lamer>yeah, if it calculated the actual time since the last frame was sent to the gpu <davexunit>a fixed timestep is a good thing, but it means that you have to do extra work to interpolate the data so that the animation is smooth on screen. <unknown_lamer>mark_weaver: is your NaN boxing patch floating around anywhere? <unknown_lamer>but for now I am focusing on generalizing the GLUT stuff in wingo's demos and making it trivial to add new demos <unknown_lamer>and then cleaning up what code I've written / filling out all of the shader and program accessors <mark_weaver>unknown_lamer: I haven't posted it yet. now it will require some updates because of the recent VM switcheroo. I'll try to get it updated soonish.