def mesh_to_staging(): global staging_mesh_buffer, staging_mesh_memory # Create staging resources staging_mesh_buffer = hvk.create_buffer( api, device, hvk.buffer_create_info(size=total_mesh_size, usage=vk.BUFFER_USAGE_TRANSFER_SRC_BIT)) staging_req = hvk.buffer_memory_requirements(api, device, staging_mesh_buffer) mt_index = find_memory_type( 0, vk.MEMORY_PROPERTY_HOST_COHERENT_BIT | vk.MEMORY_PROPERTY_HOST_VISIBLE_BIT) staging_mesh_memory = hvk.allocate_memory( api, device, hvk.memory_allocate_info(allocation_size=staging_req.size, memory_type_index=mt_index)) hvk.bind_buffer_memory(api, device, staging_mesh_buffer, staging_mesh_memory, 0) # Upload mesh to staging data data_ptr = hvk.map_memory(api, device, staging_mesh_memory, 0, staging_req.size).value memmove(data_ptr + mesh_positions['offset'], byref(mesh_positions['data']), mesh_positions['size']) memmove(data_ptr + mesh_indices['offset'], byref(mesh_indices['data']), mesh_indices['size']) hvk.unmap_memory(api, device, staging_mesh_memory)
def texture_to_staging(): global staging_texture_buffer, staging_texture_memory # Create staging resources staging_texture_buffer = hvk.create_buffer( api, device, hvk.buffer_create_info(size=len(texture.data), usage=vk.BUFFER_USAGE_TRANSFER_SRC_BIT)) staging_req = hvk.buffer_memory_requirements(api, device, staging_texture_buffer) mt_index = find_memory_type( 0, vk.MEMORY_PROPERTY_HOST_COHERENT_BIT | vk.MEMORY_PROPERTY_HOST_VISIBLE_BIT) staging_texture_memory = hvk.allocate_memory( api, device, hvk.memory_allocate_info(allocation_size=staging_req.size, memory_type_index=mt_index)) hvk.bind_buffer_memory(api, device, staging_texture_buffer, staging_texture_memory, 0) # Upload texture to staging data data_ptr = hvk.map_memory(api, device, staging_texture_memory, 0, staging_req.size).value memmove(data_ptr, texture.data_ptr(), len(texture.data)) hvk.unmap_memory(api, device, staging_texture_memory)
def _setup_meshes_resources(self, staging_alloc, staging_buffer, mesh_buffer_size): engine, api, device = self.ctx mem = engine.memory_manager cmd = engine.setup_command_buffer # Final buffer allocation mesh_buffer = hvk.create_buffer( api, device, hvk.buffer_create_info(size=mesh_buffer_size, usage=vk.BUFFER_USAGE_INDEX_BUFFER_BIT | vk.BUFFER_USAGE_VERTEX_BUFFER_BIT | vk.BUFFER_USAGE_TRANSFER_DST_BIT)) mesh_alloc = mem.alloc(mesh_buffer, vk.STRUCTURE_TYPE_BUFFER_CREATE_INFO, (vk.MEMORY_PROPERTY_DEVICE_LOCAL_BIT, )) # Uploading commands region = vk.BufferCopy(src_offset=0, dst_offset=0, size=mesh_buffer_size) regions = (region, ) hvk.begin_command_buffer(api, cmd, hvk.command_buffer_begin_info()) hvk.copy_buffer(api, cmd, staging_buffer, mesh_buffer, regions) hvk.end_command_buffer(api, cmd) # Submitting engine.submit_setup_command(wait=True) return mesh_alloc, mesh_buffer
def create_descriptor_sets(): global descriptor_pool, descriptor_set, uniforms_buffer, uniforms_mem global ubo_data_type, light_data_type, uniforms_data_type # Setup descriptor set resources ubo_data_type = Mat4 * 3 light_data_type = type( "Light", (Structure, ), { '_fields_': (('reverseLightDirection', c_float * 3), ('color', c_float * 4)) }) uniforms_data_type = type( "Uniforms", (Structure, ), {'_fields_': (('ubo', ubo_data_type), ('light', light_data_type))}) uniforms_data_size = sizeof(uniforms_data_type) # Create descriptor pool uniforms_pool_size = vk.DescriptorPoolSize( type=vk.DESCRIPTOR_TYPE_UNIFORM_BUFFER, descriptor_count=2) sampler_pool_size = vk.DescriptorPoolSize( type=vk.DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, descriptor_count=1) descriptor_pool = hvk.create_descriptor_pool( api, device, hvk.descriptor_pool_create_info(max_sets=1, pool_sizes=(uniforms_pool_size, sampler_pool_size))) descriptor_set = hvk.allocate_descriptor_sets( api, device, hvk.descriptor_set_allocate_info( descriptor_pool=descriptor_pool, set_layouts=(descriptor_set_layout, )))[0] # Allocate memory for the descriptor uniforms_buffer = hvk.create_buffer( api, device, hvk.buffer_create_info(size=uniforms_data_size, usage=vk.BUFFER_USAGE_UNIFORM_BUFFER_BIT)) ubo_buffer_req = hvk.buffer_memory_requirements(api, device, uniforms_buffer) mt_index = find_memory_type( 0, vk.MEMORY_PROPERTY_HOST_COHERENT_BIT | vk.MEMORY_PROPERTY_HOST_VISIBLE_BIT) uniforms_mem = hvk.allocate_memory( api, device, hvk.memory_allocate_info(allocation_size=ubo_buffer_req.size, memory_type_index=mt_index)) hvk.bind_buffer_memory(api, device, uniforms_buffer, uniforms_mem, 0)
def create_descriptor_sets(): global descriptor_pool, descriptor_set, color_buffer, color_mem # Uniform buffer values colors = (0.8, 0.8, 0.0, 1.0) colors_data = (c_float * len(colors))(*colors) colors_data_size = sizeof(colors_data) # Create descriptor pool pool_size = vk.DescriptorPoolSize(type=vk.DESCRIPTOR_TYPE_UNIFORM_BUFFER, descriptor_count=1) descriptor_pool = hvk.create_descriptor_pool( api, device, hvk.descriptor_pool_create_info(max_sets=1, pool_sizes=(pool_size, ))) descriptor_set = hvk.allocate_descriptor_sets( api, device, hvk.descriptor_set_allocate_info( descriptor_pool=descriptor_pool, set_layouts=(descriptor_set_layout, )))[0] # Allocate memory for the descriptor color_buffer = hvk.create_buffer( api, device, hvk.buffer_create_info(size=colors_data_size, usage=vk.BUFFER_USAGE_UNIFORM_BUFFER_BIT)) color_buffer_req = hvk.buffer_memory_requirements(api, device, color_buffer) mt_index = find_memory_type( 0, vk.MEMORY_PROPERTY_HOST_COHERENT_BIT | vk.MEMORY_PROPERTY_HOST_VISIBLE_BIT) color_mem = hvk.allocate_memory( api, device, hvk.memory_allocate_info(allocation_size=color_buffer_req.size, memory_type_index=mt_index)) hvk.bind_buffer_memory(api, device, color_buffer, color_mem, 0) # Upload color data to memory data_ptr = hvk.map_memory(api, device, color_mem, 0, colors_data_size).value memmove(data_ptr, byref(colors_data), colors_data_size) hvk.unmap_memory(api, device, color_mem)
def mesh_to_device(): global mesh_buffer, mesh_memory, staging_mesh_buffer, staging_mesh_memory, mesh_data # Create mesh resources mesh_buffer = hvk.create_buffer( api, device, hvk.buffer_create_info(size=total_mesh_size, usage=vk.BUFFER_USAGE_TRANSFER_DST_BIT | vk.BUFFER_USAGE_INDEX_BUFFER_BIT | vk.BUFFER_USAGE_VERTEX_BUFFER_BIT)) mesh_req = hvk.buffer_memory_requirements(api, device, mesh_buffer) mt_index = find_memory_type(vk.MEMORY_HEAP_DEVICE_LOCAL_BIT, vk.MEMORY_PROPERTY_DEVICE_LOCAL_BIT) mesh_memory = hvk.allocate_memory( api, device, hvk.memory_allocate_info(allocation_size=mesh_req.size, memory_type_index=mt_index)) hvk.bind_buffer_memory(api, device, mesh_buffer, mesh_memory, 0) # Upload mesh to device memory (recording) hvk.begin_command_buffer(api, staging_cmd, hvk.command_buffer_begin_info()) region = vk.BufferCopy(src_offset=0, dst_offset=0, size=mesh_req.size) hvk.copy_buffer(api, staging_cmd, staging_mesh_buffer, mesh_buffer, (region, )) hvk.end_command_buffer(api, staging_cmd) # Upload mesh to device memory (submiting) submit_info = hvk.submit_info(command_buffers=(staging_cmd, )) hvk.queue_submit(api, render_queue.handle, (submit_info, ), fence=staging_fence) hvk.wait_for_fences(api, device, (staging_fence, )) # Free staging resources hvk.destroy_buffer(api, device, staging_mesh_buffer) hvk.free_memory(api, device, staging_mesh_memory) del mesh_data, staging_mesh_buffer, staging_mesh_memory
def _setup_objects_staging(self, staging_size, data_meshes, data_images): engine, api, device = self.ctx mem = engine.memory_manager staging_buffer = hvk.create_buffer( api, device, hvk.buffer_create_info(size=staging_size, usage=vk.BUFFER_USAGE_TRANSFER_SRC_BIT)) staging_alloc = mem.alloc(staging_buffer, vk.STRUCTURE_TYPE_BUFFER_CREATE_INFO, (vk.MEMORY_PROPERTY_HOST_COHERENT_BIT | vk.MEMORY_PROPERTY_HOST_VISIBLE_BIT, )) with mem.map_alloc(staging_alloc) as alloc: for dm in data_meshes: alloc.write_bytes(dm.base_offset, dm.as_ctypes_array()) for di in data_images: alloc.write_bytes(di.base_staging_offset, di.as_ctypes_array()) return staging_alloc, staging_buffer
def _setup_descriptor_sets(self): engine, api, device = self.ctx shaders, computes = self.shaders, self.computes descriptor_pool = self.descriptor_pool mem = engine.memory_manager uniforms_buffer_size = 0 # Allocate shader global descriptor sets for data_shader in shaders: uniforms_buffer_size += sum(l.struct_map_size_bytes for l in data_shader.global_layouts) set_layouts_global = [ l.set_layout for l in data_shader.global_layouts ] if len(set_layouts_global) == 0: data_shader.descriptor_sets = [] continue descriptor_sets = hvk.allocate_descriptor_sets( api, device, hvk.descriptor_set_allocate_info( descriptor_pool=descriptor_pool, set_layouts=set_layouts_global)) data_shader.descriptor_sets = descriptor_sets # Allocate compute shader global descriptor sets for data_compute in computes: uniforms_buffer_size += sum(l.struct_map_size_bytes for l in data_compute.global_layouts) set_layouts_global = [ l.set_layout for l in data_compute.global_layouts ] if len(set_layouts_global) == 0: data_compute.descriptor_sets = [] continue descriptor_sets = hvk.allocate_descriptor_sets( api, device, hvk.descriptor_set_allocate_info( descriptor_pool=descriptor_pool, set_layouts=set_layouts_global)) data_compute.descriptor_sets = descriptor_sets # Allocate object local descriptor sets for shader_index, objects in self._group_objects_by_shaders(): shader = shaders[shader_index] objlen = len(objects) # Uniforms buffer size uniforms_buffer_size += sum(l.struct_map_size_bytes for l in shader.local_layouts) * objlen # Descriptor sets allocations set_layouts_local = [l.set_layout for l in shader.local_layouts] * objlen if len(set_layouts_local) == 0: for obj in objects: obj.descriptor_sets = [] continue descriptor_sets = hvk.allocate_descriptor_sets( api, device, hvk.descriptor_set_allocate_info( descriptor_pool=descriptor_pool, set_layouts=set_layouts_local)) # Save the local layouts to the objects step = len(tuple(shader.local_layouts)) if step == 0: continue end = len(descriptor_sets) iter_objects = iter(objects) for i in range(0, end, step): obj = next(iter_objects) obj.descriptor_sets = descriptor_sets[i:i + step] # Uniform buffer creation if uniforms_buffer_size == 0: self.uniforms_alloc = self.uniforms_buffer = None return uniforms_buffer = hvk.create_buffer( api, device, hvk.buffer_create_info(size=uniforms_buffer_size, usage=vk.BUFFER_USAGE_UNIFORM_BUFFER_BIT)) uniforms_alloc = mem.alloc(uniforms_buffer, vk.STRUCTURE_TYPE_BUFFER_CREATE_INFO, (vk.MEMORY_PROPERTY_HOST_VISIBLE_BIT | vk.MEMORY_PROPERTY_HOST_COHERENT_BIT, )) # Make sure the uniforms are zeroed with mem.map_alloc(uniforms_alloc) as mapping: memset(mapping.pointer2, 0, uniforms_alloc.size) self.uniforms_alloc = uniforms_alloc self.uniforms_buffer = uniforms_buffer