def __init__(self, ctx, queue, z_bounds, init_chunk_array_kernel): ''' ''' num_layers = z_bounds[1] - z_bounds[0] self.array_buffer = RenderBuffer(ctx, queue, self.dtype_array.itemsize, 0) # may not grow self.layer_buffer = RenderBuffer(ctx, queue, 2**14, 2**12) self.chunk_buffer = RenderBuffer(ctx, queue, 2**14, 2**12) # The chunks self.data, offset = self.array_buffer.allocate_data(self.dtype_array) self.layers = [ ChunkLayer(*self.layer_buffer.allocate_data(self.dtype_layer)) for i in range(num_layers) ] self.z_bounds = z_bounds self.x_bounds = (2**30, -2**30) self.y_bounds = (2**30, -2**30) self.chunk_layers_ptr = self.layer_buffer._d_buffer.int_ptr self.voxel_data = VoxelData(ctx, queue) self.init_chunk_array_kernel = init_chunk_array_kernel self.ctx = ctx self.queue = queue
class ChunkArray(object): ''' Stores chunk layers in a array structure. ''' dtype_array = numpy.dtype( [ ('x_bounds', numpy.int32, 2), ('y_bounds', numpy.int32, 2), ('z_bounds', numpy.int32, 2), ('chunk_layers_ptr', numpy.uintp), ('chunks_ptr', numpy.uintp), ('voxel_levels_ptr', numpy.uintp, 6) ] ) dtype_layer = numpy.dtype( [ ('x_bounds', numpy.int32, 2), ('y_bounds', numpy.int32, 2), ('chunk_offset', numpy.uint32) ] ) dtype_chunk = numpy.dtype( [ ('level', numpy.int), ('voxel_offset', numpy.uint32) ] ) def __init__(self, ctx, queue, z_bounds, init_chunk_array_kernel): ''' ''' num_layers = z_bounds[1] - z_bounds[0] self.array_buffer = RenderBuffer(ctx, queue, self.dtype_array.itemsize, 0) # may not grow self.layer_buffer = RenderBuffer(ctx, queue, 2**14, 2**12) self.chunk_buffer = RenderBuffer(ctx, queue, 2**14, 2**12) # The chunks self.data, offset = self.array_buffer.allocate_data(self.dtype_array) self.layers = [ ChunkLayer(*self.layer_buffer.allocate_data(self.dtype_layer)) for i in range(num_layers) ] self.z_bounds = z_bounds self.x_bounds = (2**30, -2**30) self.y_bounds = (2**30, -2**30) self.chunk_layers_ptr = self.layer_buffer._d_buffer.int_ptr self.voxel_data = VoxelData(ctx, queue) self.init_chunk_array_kernel = init_chunk_array_kernel self.ctx = ctx self.queue = queue def get_layer(self, z): if z < self.z_bounds[0] or z >= self.z_bounds[1]: raise IndexError("%d index is out of bounds (layer not found)" % z) return self.layers[z - self.z_bounds[0]] def get_chunk(self, x, y, z): layer = self.get_layer(z) if (x < layer.x_bounds[0] or x >= layer.x_bounds[1] or y < layer.y_bounds[0] or y >= layer.y_bounds[1]): raise IndexError("Layer %d found, but not chunk (%d, %d) in it. " % (z, x, y)) x_offset = x - layer.x_bounds[0] y_offset = y - layer.y_bounds[0] return layer.chunks[x_offset + y_offset*(layer.y_bounds[1]-layer.y_bounds[0])] def get_voxel(self, x, y, z): chunk_x, voxel_x = divmod(x, 32) chunk_y, voxel_y = divmod(y, 32) chunk_z, voxel_z = divmod(z, 32) chunk = self.get_chunk(chunk_x, chunk_y, chunk_z) return chunk.get_voxel((voxel_x, voxel_y, voxel_z)) def allocate_layer(self, z, x_bounds, y_bounds): layer = self.get_layer(z) x_size = x_bounds[1] - x_bounds[0] y_size = y_bounds[1] - y_bounds[0] if x_bounds[0] < self.x_bounds[0]: self.x_bounds[0] = x_bounds[0] if x_bounds[1] > self.x_bounds[1]: self.x_bounds[1] = x_bounds[1] if y_bounds[0] < self.y_bounds[0]: self.y_bounds[0] = y_bounds[0] if y_bounds[1] > self.y_bounds[1]: self.y_bounds[1] = y_bounds[1] layer.x_bounds = x_bounds layer.y_bounds = y_bounds layer.chunks = [ Chunk(*self.chunk_buffer.allocate_data(self.dtype_chunk)) for i in range(x_size*y_size) ] layer.chunk_offset = layer.chunks[0].offset / self.dtype_chunk.itemsize def allocate_chunk(self, x, y, z, level): chunk = self.get_chunk(x, y, z) chunk.level = level data, offset = self.voxel_data.allocate_buffer(level) chunk.voxel_offset = offset / self.voxel_data.test_dtype.itemsize chunk.voxel_data = data def upload_buffers(self): self.array_buffer.upload_buffer() self.layer_buffer.upload_buffer() self.chunk_buffer.upload_buffer() self.voxel_data.upload_buffers() self.init_chunk_array_kernel(self.queue, (1,), None, self.array_buffer._d_buffer, self.layer_buffer._d_buffer, self.chunk_buffer._d_buffer, *[ self.voxel_data.level_buffers[i]._d_buffer for i in range(self.voxel_data.num_levels) ]) self.array_buffer.download_buffer() @render_property("x_bounds") def x_bounds(self): "x_min, x_max" @render_property("y_bounds") def y_bounds(self): "y_min, y_max" @render_property("z_bounds") def z_bounds(self): "z_min, z_max" @render_property("chunk_layers_ptr", None) def chunk_layers_ptr(self): "chunk_layer_t*" @render_property("chunks_ptr", None) def chunks_ptr(self): "chunk_t*" @render_property("voxel_levels_ptr") def voxel_levels_ptr(self): "voxel_t* [6]"