Beispiel #1
0
    def from_uncompressed(cls, data, **kwargs):
        keys = tuple(kwargs.keys())
        if ("format" not in keys) or ("extent" not in keys):
            raise ValueError(
                "Image `format` and `extent` must be specified as keyword arguments"
            )
        if kwargs.get("no_default_view",
                      False) == False and ("default_view_type" not in keys):
            raise ValueError(
                "If a default image view is generated, `default_view_type` must be specified as a keyword argument"
            )

        image = super().__new__(cls)
        image.__init__(**kwargs)

        image.source_type = ImageSource.Uncompressed
        image.source = data

        image.flags = kwargs.get('flags', 0)
        image.format = kwargs["format"]
        image.extent = kwargs["extent"]
        image.mipmaps_levels = 1
        image.texture_size = len(data)
        image.array_layers = 1

        if kwargs.get("no_default_view", False) != True:
            subs_range = hvk.image_subresource_range(
                level_count=image.mipmaps_levels,
                layer_count=image.array_layers)
            image.views["default"] = ImageView.from_params(
                view_type=kwargs["default_view_type"],
                format=image.format,
                subresource_range=subs_range)

        return image
Beispiel #2
0
    def from_ktx(cls, ktx_file, **kwargs):
        f = ktx_file
        if not isinstance(f, KTXFile):
            raise RuntimeError(
                f"File must be KTXFile, got {type(f).__qualname__}")

        image = super().__new__(cls)
        image.__init__(**kwargs)

        image.source_type = ImageSource.Ktx
        image.source = f

        image.flags = f.vk_flags
        image.format = f.vk_format
        image.extent = (f.width, f.height, f.depth)
        image.mipmaps_levels = f.mips_level
        image.texture_size = f.texture_size
        image.array_layers = f.faces * f.array_element

        if kwargs.get("no_default_view", False) != True:
            subs_range = hvk.image_subresource_range(
                level_count=f.mips_level, layer_count=image.array_layers)
            image.views["default"] = ImageView.from_params(
                view_type=f.vk_view_type,
                format=f.vk_format,
                subresource_range=subs_range)

        return image
Beispiel #3
0
    def _setup_depth_stencil(self):
        engine, api, device = self.ctx
        width, height = engine.info["swapchain_extent"].values()
        depth_format = engine.info["depth_format"]
        mem = engine.memory_manager

        if self.depth_stencil is not None:
            hvk.destroy_image_view(api, device, self.depth_stencil.view)
            hvk.destroy_image(api, device, self.depth_stencil.image)
            mem.free_alloc(self.depth_stencil_alloc)

        depth_stencil_image = 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))

        alloc = mem.alloc(depth_stencil_image,
                          vk.STRUCTURE_TYPE_IMAGE_CREATE_INFO,
                          types=(vk.MEMORY_PROPERTY_DEVICE_LOCAL_BIT, ))

        depth_stencil_view = hvk.create_image_view(
            api, device,
            hvk.image_view_create_info(
                image=depth_stencil_image,
                format=depth_format,
                subresource_range=hvk.image_subresource_range(
                    aspect_mask=vk.IMAGE_ASPECT_DEPTH_BIT
                    | vk.IMAGE_ASPECT_STENCIL_BIT)))

        self.depth_stencil = ImageAndView(image=depth_stencil_image,
                                          view=depth_stencil_view)
        self.depth_stencil_alloc = alloc
Beispiel #4
0
 def __init__(self, **kw):
     self.params = dict(view_type=kw.get('view_type',
                                         vk.IMAGE_VIEW_TYPE_2D),
                        format=kw['format'],
                        components=kw.get('components',
                                          hvk.component_mapping()),
                        subresource_range=kw.get(
                            'subresource_range',
                            hvk.image_subresource_range()))
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)))
Beispiel #6
0
    def device_update_image_layout(api, cmd_buffer, queue, cmd_data,
                                   data_scene):
        data_image = data_scene.images[cmd_data["image_id"]]
        image = data_image.image

        data_image.update_layout(cmd_data["new_layout"])
        queue_flags = queue.family.properties.queue_flags
        dst_stage_mask = hvk.dst_stage_mask_for_access_mask(
            data_image.target_access_mask, queue_flags=queue_flags)

        change_layout = hvk.image_memory_barrier(
            image=data_image.image_handle,
            old_layout=data_image.layout,
            new_layout=data_image.target_layout,
            src_access_mask=data_image.access_mask,
            dst_access_mask=data_image.target_access_mask,
            subresource_range=hvk.image_subresource_range(
                level_count=image.mipmaps_levels,
                layer_count=image.array_layers))

        hvk.pipeline_barrier(api,
                             cmd_buffer, (change_layout, ),
                             dst_stage_mask=dst_stage_mask)
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
Beispiel #8
0
    def _setup_image_layouts(self, staging_buffer, data_images):
        engine, api, device = self.ctx

        to_transfer = hvk.image_memory_barrier(
            image=0,
            new_layout=vk.IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
            dst_access_mask=vk.ACCESS_TRANSFER_WRITE_BIT,
            subresource_range=hvk.image_subresource_range(level_count=0))

        to_final_layout = hvk.image_memory_barrier(
            image=0,
            old_layout=vk.IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
            new_layout=0,
            src_access_mask=vk.ACCESS_TRANSFER_WRITE_BIT,
            dst_access_mask=0,
            subresource_range=hvk.image_subresource_range(level_count=0))

        cmd = engine.setup_command_buffer
        hvk.begin_command_buffer(api, cmd, hvk.command_buffer_begin_info())

        for data_image in data_images:
            image = data_image.image
            image_handle = data_image.image_handle
            regions = []

            for m in image.iter_mipmaps():
                r = hvk.buffer_image_copy(
                    image_subresource=hvk.image_subresource_layers(
                        mip_level=m.level, base_array_layer=m.layer),
                    image_extent=vk.Extent3D(m.width, m.height, 1),
                    buffer_offset=data_image.base_staging_offset + m.offset)
                regions.append(r)

            to_transfer.image = image_handle
            to_transfer.subresource_range.level_count = image.mipmaps_levels
            to_transfer.subresource_range.layer_count = image.array_layers

            to_final_layout.image = image_handle
            to_final_layout.new_layout = data_image.target_layout
            to_final_layout.dst_access_mask = data_image.target_access_mask
            to_final_layout.subresource_range.level_count = image.mipmaps_levels
            to_final_layout.subresource_range.layer_count = image.array_layers

            hvk.pipeline_barrier(api,
                                 cmd, (to_transfer, ),
                                 dst_stage_mask=vk.PIPELINE_STAGE_TRANSFER_BIT)
            hvk.copy_buffer_to_image(api, cmd, staging_buffer, image_handle,
                                     vk.IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                                     regions)
            hvk.pipeline_barrier(
                api,
                cmd, (to_final_layout, ),
                dst_stage_mask=hvk.dst_stage_mask_for_access_mask(
                    to_final_layout.dst_access_mask))

        hvk.end_command_buffer(api, cmd)

        # Sumbit the images and update the layer values in the images
        engine.submit_setup_command(wait=True)
        for img in data_images:
            img.layout = img.target_layout
            img.access_mask = img.target_access_mask