Open dalev opened 2 years ago
You can probably get most or all blocking APIs from vk.xml by searching for commands that list VK_TIMEOUT
as a success code, and/or have a uint64_t
parameter called timeout
. The spec is very precise about how things should be named, so I imagine this is no exception. vkAcquireNextImageKHR
is an example of such a function.
Some of these are more important than others to handle correctly though. From a practical standpoint, most graphics applications avoid doing any kind of synchronization with the GPU with ideally the only API stalls being from presenting the final image.
You have the right idea though. Any time your application's render thread would be blocked by such a thing, it is best to run background tasks, and Racket's GC is a good candidate for that sort of thing.
Some Vulkan calls may block the calling (OS) thread. E.g.,
vkWaitForFences
,vkDeviceWaitIdle
, etc.Cooperation with Racket's runtime could be improved by adding
#:blocking? #t
to those procedures' FFI_fun
types. Without that, these procedures may prevent the runtime from making progress on other activies such as GC.(Note that this is even true if one were to "silo" Vulkan calls in a dedicated OS thread usingracket/place
.)Now, I don't see anything in
vk.xml
that definitively identifies blocking calls, but maybe it's enough to simply scan for "Wait" in the name of the procedure?Btw, this is somewhat related to issue #24: with
#:blocking? #t
, you don't want arguments to these procedures to be moved around in memory.Fwiw, I can think of potential two work-arounds (untested!):
(1) Use
call-in-os-thread
to wrap blocking calls, andmake-os-async-channel
+sync
to block in a runtime-friendly manner.(2) Try extensions like
vkGetFenceFdKHR
+unsafe-file-descriptor->port
. Thensync
on the port.But these both seem unnecessarily complicated (and they don't obviate the need for
'atomic-interior
allocations.)Edit: So, Ryan's talk about how the DB library handles blocking FFI calls is useful. IIUC, a blocking FFI call also blocks any racket (green) threads that were created in that OS thread. So, for a program to remain responsive, it needs blocking FFI calls marked with
#:blocking? #t
and also to invoke them usingcall-in-os-thread
. (Or avoid the blocking call entirely with an approach like (2).) All that to say, I was wrong to characterize (1) as a work-around; rather, it's a point in the design space that programmers can consider once#:blocking? #t
is available.