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_swapchain_depth_stencil(recreate=False): global depth_format, depth_stencil, depth_alloc, depth_view if recreate: hvk.destroy_image_view(api, device, depth_view) hvk.destroy_image(api, device, depth_stencil) hvk.free_memory(api, device, depth_alloc) width, height = window.dimensions() # Depth stencil attachment setup depth_format = None depth_formats = (vk.FORMAT_D32_SFLOAT_S8_UINT, vk.FORMAT_D24_UNORM_S8_UINT, vk.FORMAT_D16_UNORM_S8_UINT) for fmt in depth_formats: prop = hvk.physical_device_format_properties(api, physical_device, fmt) if IntFlag(vk.FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) in IntFlag( prop.optimal_tiling_features): depth_format = fmt break if depth_format is None: raise RuntimeError("Failed to find a suitable depth stencil format.") # Depth stencil image creation depth_stencil = hvk.create_image( api, device, hvk.image_create_info(format=depth_format, extent=vk.Extent3D(width=width, height=height, depth=1), usage=vk.IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | vk.IMAGE_USAGE_TRANSFER_SRC_BIT)) # Depth stencil image memory image_memreq = hvk.image_memory_requirements(api, device, depth_stencil) mt_index = find_memory_type(vk.MEMORY_HEAP_DEVICE_LOCAL_BIT, vk.MEMORY_PROPERTY_DEVICE_LOCAL_BIT) depth_stencil_size = image_memreq.size * 2 depth_alloc = hvk.allocate_memory( api, device, hvk.memory_allocate_info(allocation_size=depth_stencil_size, memory_type_index=mt_index)) hvk.bind_image_memory(api, device, depth_stencil, depth_alloc) # Depth stencil image view depth_view = hvk.create_image_view( api, device, hvk.image_view_create_info( image=depth_stencil, format=depth_format, subresource_range=hvk.image_subresource_range( aspect_mask=vk.IMAGE_ASPECT_DEPTH_BIT | vk.IMAGE_ASPECT_STENCIL_BIT)))
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 shared_alloc(self, size, types): _, api, device = self.ctx memory_type_index = self._get_memory_type_index(types) device_memory = hvk.allocate_memory( api, device, hvk.memory_allocate_info(allocation_size=size, memory_type_index=memory_type_index)) alloc = SharedAlloc(device_memory, size) self.allocations.append(alloc) return weakref.proxy(alloc)
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 create_noise_image_output(): global noise_image, noise_view, noise_alloc, noise_sampler # Noise image noise_image = hvk.create_image( api, device, hvk.image_create_info(format=vk.FORMAT_B8G8R8A8_UNORM, extent=vk.Extent3D(width=256, height=256, depth=1), usage=vk.IMAGE_USAGE_STORAGE_BIT | vk.IMAGE_USAGE_SAMPLED_BIT)) noise_memreq = hvk.image_memory_requirements(api, device, noise_image) mt_index = find_memory_type(vk.MEMORY_HEAP_DEVICE_LOCAL_BIT, vk.MEMORY_PROPERTY_DEVICE_LOCAL_BIT) noise_alloc = hvk.allocate_memory( api, device, hvk.memory_allocate_info(allocation_size=noise_memreq.size, memory_type_index=mt_index)) hvk.bind_image_memory(api, device, noise_image, noise_alloc) # Noise view noise_view = hvk.create_image_view( api, device, hvk.image_view_create_info(image=noise_image, format=vk.FORMAT_B8G8R8A8_UNORM)) # Noise sampler noise_sampler = hvk.create_sampler( api, device, hvk.sampler_create_info( mag_filter=vk.FILTER_LINEAR, min_filter=vk.FILTER_LINEAR, ))
def alloc(self, resource, resource_type, types): _, api, device = self.ctx requirements = self.get_resource_requirements(resource, resource_type) memory_type_index = self._get_memory_type_index(types) device_memory = hvk.allocate_memory( api, device, hvk.memory_allocate_info(allocation_size=requirements.size, memory_type_index=memory_type_index)) if resource_type == vk.STRUCTURE_TYPE_IMAGE_CREATE_INFO: hvk.bind_image_memory(api, device, resource, device_memory) elif resource_type == vk.STRUCTURE_TYPE_BUFFER_CREATE_INFO: hvk.bind_buffer_memory(api, device, resource, device_memory, 0) else: raise ValueError( "value of argument \"resource_type\" must be STRUCTURE_TYPE_IMAGE_CREATE_INFO or STRUCTURE_TYPE_BUFFER_CREATE_INFO" ) alloc = Alloc(resource, device_memory, requirements.size) self.allocations.append(alloc) return weakref.proxy(alloc)
def texture_to_device(): global texture_image, texture_image_memory, texture_image_layout, texture_view, texture_sampler global texture, staging_texture_buffer, staging_texture_memory # Create the vulkan image texture_image_layout = vk.IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL texture_image = hvk.create_image( api, device, hvk.image_create_info( format=texture.format, mip_levels=len(texture.mipmaps), extent=vk.Extent3D(texture.width, texture.height, texture.depth), usage=vk.IMAGE_USAGE_TRANSFER_DST_BIT | vk.IMAGE_USAGE_SAMPLED_BIT, )) img_req = hvk.image_memory_requirements(api, device, texture_image) mt_index = find_memory_type(vk.MEMORY_HEAP_DEVICE_LOCAL_BIT, vk.MEMORY_HEAP_DEVICE_LOCAL_BIT) texture_image_memory = hvk.allocate_memory( api, device, hvk.memory_allocate_info(allocation_size=img_req.size, memory_type_index=mt_index)) hvk.bind_image_memory(api, device, texture_image, texture_image_memory, 0) # Build the copy regions (1 for each mipmap) regions = [] for i, m in enumerate(texture.mipmaps): region = hvk.buffer_image_copy( image_subresource=hvk.image_subresource_layers(mip_level=i), image_extent=vk.Extent3D(m.width, m.height, 1), buffer_offset=m.offset) regions.append(region) # Build the image barrier for the image layout transitions barrier = hvk.image_memory_barrier( image=texture_image, new_layout=0, dst_access_mask=0, subresource_range=hvk.image_subresource_range( level_count=len(texture.mipmaps))) # Transfer the staging data to device hvk.begin_command_buffer(api, staging_cmd, hvk.command_buffer_begin_info()) barrier.new_layout = vk.IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL barrier.dst_access_mask = vk.ACCESS_TRANSFER_WRITE_BIT hvk.pipeline_barrier(api, staging_cmd, (barrier, ), dst_stage_mask=vk.PIPELINE_STAGE_TRANSFER_BIT) hvk.copy_buffer_to_image(api, staging_cmd, staging_texture_buffer, texture_image, vk.IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, regions) barrier.old_layout = vk.IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL barrier.new_layout = vk.IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL barrier.src_access_mask = vk.ACCESS_TRANSFER_WRITE_BIT barrier.dst_access_mask = vk.ACCESS_SHADER_READ_BIT hvk.pipeline_barrier(api, staging_cmd, (barrier, ), dst_stage_mask=vk.PIPELINE_STAGE_FRAGMENT_SHADER_BIT) hvk.end_command_buffer(api, staging_cmd) # Submit the staging command buffer hvk.reset_fences(api, device, (staging_fence, )) 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, )) # Create the image view and the sampler texture_view = hvk.create_image_view( api, device, hvk.image_view_create_info( image=texture_image, format=texture.format, subresource_range=hvk.image_subresource_range( level_count=len(texture.mipmaps)))) texture_sampler = hvk.create_sampler( api, device, hvk.sampler_create_info( mag_filter=vk.FILTER_LINEAR, min_filter=vk.FILTER_LINEAR, max_lod=len(texture.mipmaps), )) # Free staging resources hvk.destroy_buffer(api, device, staging_texture_buffer) hvk.free_memory(api, device, staging_texture_memory) del texture, staging_texture_buffer, staging_texture_memory