Beispiel #1
0
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)
Beispiel #5
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
Beispiel #8
0
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,
        ))
Beispiel #9
0
    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