示例#1
0
    def _setup_objects(self):
        engine, api, device = self.ctx
        mem = engine.memory_manager

        scene = self.scene
        meshes = scene.meshes
        images = scene.images

        staging_mesh_offset = 0
        data_meshes, data_objects, data_images, data_samplers = [], [], [], []

        # Objects setup
        for obj in scene.objects:
            data_objects.append(DataGameObject(obj))

        # Samplers
        for sampler in scene.samplers:
            data_samplers.append(DataSampler(engine, sampler))

        # Meshes setup
        for mesh in meshes:
            data_mesh = DataMesh(mesh, staging_mesh_offset)
            data_meshes.append(data_mesh)
            staging_mesh_offset += mesh.size()

        # Images
        staging_image_offset = (
            staging_mesh_offset + 256
        ) & ~255  # staging_image_offset must be aligned to 256 bits for uploading purpose

        for image in images:
            data_image = DataImage(engine, image, staging_image_offset)
            data_images.append(data_image)
            staging_image_offset += image.size()

        if len(meshes) == 0 and len(images) == 0:
            staging_alloc = staging_buffer = meshes_alloc = meshes_buffer = images_alloc = None
        else:
            staging_alloc, staging_buffer = self._setup_objects_staging(
                staging_image_offset, data_meshes, data_images)
            meshes_alloc = meshes_buffer = images_alloc = None
            if len(meshes) > 0:
                meshes_alloc, meshes_buffer = self._setup_meshes_resources(
                    staging_alloc, staging_buffer, staging_mesh_offset)
            if len(images) > 0:
                images_alloc = self._setup_images_resources(
                    staging_alloc, staging_buffer, data_images)

        self.meshes_alloc = meshes_alloc
        self.meshes_buffer = meshes_buffer
        self.meshes = data_meshes
        self.images_alloc = images_alloc
        self.images = data_images
        self.samplers = data_samplers
        self.objects = data_objects

        if staging_buffer is not None:
            hvk.destroy_buffer(api, device, staging_buffer)
            mem.free_alloc(staging_alloc)
def clean_resources():
    window.hide()
    hvk.device_wait_idle(api, device)

    hvk.destroy_fence(api, device, staging_fence)
    hvk.destroy_command_pool(api, device, staging_pool)

    hvk.destroy_command_pool(api, device, drawing_pool)

    hvk.destroy_buffer(api, device, mesh_buffer)
    hvk.free_memory(api, device, mesh_memory)

    hvk.destroy_sampler(api, device, texture_sampler)
    hvk.destroy_image_view(api, device, texture_view)
    hvk.destroy_image(api, device, texture_image)
    hvk.free_memory(api, device, texture_image_memory)

    hvk.destroy_descriptor_pool(api, device, descriptor_pool)
    hvk.destroy_buffer(api, device, uniforms_buffer)
    hvk.free_memory(api, device, uniforms_mem)

    hvk.destroy_pipeline(api, device, pipeline)
    hvk.destroy_pipeline_cache(api, device, pipeline_cache)
    hvk.destroy_pipeline_layout(api, device, pipeline_layout)

    for m in shader_modules:
        hvk.destroy_shader_module(api, device, m)

    hvk.destroy_descriptor_set_layout(api, device, descriptor_set_layout)

    for fb in framebuffers:
        hvk.destroy_framebuffer(api, device, fb)

    hvk.destroy_render_pass(api, device, render_pass)

    hvk.destroy_semaphore(api, device, image_ready)
    hvk.destroy_semaphore(api, device, rendering_done)
    for f in render_fences:
        hvk.destroy_fence(api, device, f)

    hvk.destroy_image(api, device, depth_stencil)
    hvk.destroy_image_view(api, device, depth_view)
    hvk.free_memory(api, device, depth_alloc)

    for v in swapchain_image_views:
        hvk.destroy_image_view(api, device, v)

    hvk.destroy_swapchain(api, device, swapchain)
    hvk.destroy_device(api, device)
    hvk.destroy_surface(api, instance, surface)

    debugger.stop()
    hvk.destroy_instance(api, instance)

    window.destroy()
示例#3
0
    def free(self):
        engine, api, device = self.ctx
        mem = engine.memory_manager

        if self.uniforms_alloc is not None:
            hvk.destroy_buffer(api, device, self.uniforms_buffer)
            mem.free_alloc(self.uniforms_alloc)

        if self.descriptor_pool is not None:
            hvk.destroy_descriptor_pool(api, device, self.descriptor_pool)

        for pipeline in self.pipelines:
            hvk.destroy_pipeline(api, device, pipeline)

        for pipeline in self.compute_pipelines:
            hvk.destroy_pipeline(api, device, pipeline)

        hvk.destroy_pipeline_cache(api, device, self.pipeline_cache)

        if self.meshes_buffer is not None:
            hvk.destroy_buffer(api, device, self.meshes_buffer)
            mem.free_alloc(self.meshes_alloc)

        for sampler in self.samplers:
            sampler.free()

        for img in self.images:
            for view in img.views.values():
                hvk.destroy_image_view(api, device, view)

            img.free()

        if self.images_alloc is not None:
            mem.free_alloc(self.images_alloc)

        for compute in self.computes:
            compute.free()

        for shader in self.shaders:
            shader.free()

        hvk.destroy_command_pool(api, device, self.command_pool)

        for _, pool in self.compute_pools:
            hvk.destroy_command_pool(api, device, pool)

        # Make it easier for python to deal with the circular dependencies
        del self.engine
        del self.scene
        del self.shaders
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 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