DrEvil wrote:
Is there a forum thread or documentation that outlines the wishlist of threading? I just want to understand the terminology people are using before I try to lend any potential threading solutions.
There is some information here about the situation as I currently understand it:
http://www.volumesoffun.com/polyvox/doc ... ading.htmlDrEvil wrote:
It sounds like the situation is that you generally use the surface extractor at a different 'resolution' than the voxel chunk size might be set up with(for paging in the data?), and this is where the threading complexities arise. Is there a reason that has to be the case? As it sounds like if those regions were one in the same, it could simplify things.
PolyVox does indeed allow the size of the extracted mesh to be different than the block size of the volume ('block' is the PolyVox name for 'chunk'). But actually it is more general that this - PolyVox does not require the volume to be composed of blocks at all (the RawVolume is just one large piece of data) and also supports algorithms beyond surface extraction (blurring the volume is an example of where handling block edges would be tricky if PolyVox did no already handle it).
Generally we try to see the use of blocks as an implementation detail of the LargeVolume.
DrEvil wrote:
Is this primarily meant to address the concurrency issue of the surface extractor building a new render mesh for something potentially in parallel with game logic modifying the voxel data?
I think there are two (possibly distinct) scenarios.
1. The data is not being modified, and the user wishes to run multiple surface extraction at the same time. In this case the biggest issue is that reading a block (chunk) may cause a different block to get paged out of memory, even if one of the other surface extractors is using it. We can probably deal with this by 'pinning' blocks which are currently in use so they don't get paged out of memory.
2. The data is also being modified at the same time. This is more complex, and perhaps a double buffering scheme as you propose could be useful.
DrEvil wrote:
Is there any reason why a simpleish deferred modification scheme cannot be employed on the application side? For example, if an explosion goes off, it can query the region of voxels is affects to see if they are in-use by a surface extractor. If any are in a currently marked in-use region, the effects of the explosion are queued and deferred, to be tried again after a simple dependency resolution(when all overlapping extractors are finished, via extractor callbacks or whatever. This in-use marking can probably be done with a simple lockless data structure that holds a list of voxel bounding boxes or something, and actual thread locking could potentially be avoided altogether. In my experience, using thread locking primitives in the game loop is to be avoided and only used as a last resort. Deferring operations, double buffering, or performing it when possible at a stage of the frame that the threads are finished(sync/join points) would be evaluated and locks only used as a last resort.
I think something like this is possible though I have little experience in the area. I think it will be more efficient to do some of this at the application level rather than the PolyVox level, but we might want to expose a bit more information from PolyVox (the fact that the volume is built from blocks, which ones are loaded, etc) to make this easier for the user to implement.