#egui #vulkan #ash #command-buffer

egui-ash-renderer

使用Ash的egui Vulkan渲染器

5个版本 (破坏性更新)

0.5.0 2024年7月17日
0.4.0 2024年7月5日
0.3.0 2024年5月1日
0.2.0 2024年3月26日
0.1.0 2024年3月16日

#153 in 图形API

Download history 143/week @ 2024-04-26 58/week @ 2024-05-03 5/week @ 2024-05-10 10/week @ 2024-05-17 4/week @ 2024-05-24 4/week @ 2024-05-31 4/week @ 2024-06-07 112/week @ 2024-07-05 115/week @ 2024-07-12 25/week @ 2024-07-19 24/week @ 2024-07-26 5/week @ 2024-08-02

每月下载量 78

MIT许可证

86KB
1.5K SLoC

egui-ash-renderer

Version Docs.rs Build Status Publish Status

使用Ash为egui提供的Vulkan渲染器。

此库旨在为您的现有Vulkan/ash应用程序添加对egui的支持。不是Vulkan/ash的完整eframe集成。

screenshot

兼容性

crate egui ash gpu-allocator (功能) vk-mem (功能)
0.5.0 [0.26, 0.28] 0.38 0.27 0.4
0.4.0 [0.26, 0.28] [0.34, 0.37] [0.25, 0.26] 0.3

工作原理

渲染器将绘制命令记录到应用程序提供的命令缓冲区中。以下是此crate的功能及其工作方式的简要说明。

顶点/索引缓冲区

每次调用Renderer::cmd_draw时,渲染器都会创建一个顶点缓冲区和索引缓冲区。如果顶点/索引计数超过缓冲区实际能容纳的值,则缓冲区会进行扩展(实际上是被销毁然后重新创建)。

飞行帧

渲染器支持同时拥有多个飞行帧。您需要在初始化渲染器时指定帧的数量。渲染器会为每个帧管理一个顶点缓冲区和索引缓冲区。

不执行绘制调用

Renderer::cmd_draw仅将命令记录到应用程序提供的命令缓冲区中。它不会将任何内容提交到GPU。

sRGB/线性帧缓冲区

您可以通过在初始化渲染器时传递选项srgb_framebuffer来指示是否针对sRGB帧缓冲区。当您针对sRGB帧缓冲区时,片段着色器将输出线性颜色值,否则它将颜色转换为sRGB。

管理的纹理

由egui管理的纹理必须与渲染器保持同步。为此,用户应调用Renderer::set_texturesRenderer::free_textures。前者必须在提交命令缓冲区进行渲染之前调用,后者必须在渲染完成后调用。示例

let output = egui_ctx.run(raw_input, |ui| {
    // ui code ..
});

// before rendering the ui
renderer.set_textures(queue, command_pool, output.textures_delta.set.as_slice()).unwrap();

// rendering code goes here .. (calling cmd_draw, submitting the command buffer, waiting for rendering to be finished...)

// after the rendering is done 
renderer.free_textures(output.textures_delta.free.as_slice()).unwrap();

如果您有多个正在运行的帧,您可能需要为每个帧保留一组纹理以供释放,并在等待上一帧的fence之后调用Renderer::free_textures

自定义纹理

您还可以在egui中渲染已使用的托管纹理。您只需要调用Renderer::add_user_texture并传递一个与渲染器图形管线中使用的布局兼容的vk::DescriptorSet(参见create_vulkan_descriptor_set_layout)。这将返回一个您可以用于UI代码的egui::TextureId。示例

let user_texture_set: vk::DescriptorSet = ...;
let texture_id = renderer.add_user_texture(user_texture_set);

let output = egui_ctx.run(raw_input, |ui| {
    let egui_texture = SizedTexture {
        id: texture_id,
        size: Vec2 {
            x: 128.0,
            y: 128.0,
        },
    };

    egui::Image::new(egui_texture).ui(ui);
});

// When the texture won't be used anymore you can remove it from the renderer
renderer.remove_user_texture(texture_id);

您可以在这里找到使用egui托管和用户托管纹理的示例。

特性

gpu-allocator

此功能添加了对gpu-allocator的支持。它添加了Renderer::with_gpu_allocator,它接受一个Arc<Mutex<gpu_allocator::vulkan::Allocator>>。所有内部分配器都使用分配器执行。

vk-mem

此功能添加了对vk-mem-rs的支持。它添加了Renderer::with_vk_mem_allocator,它接受一个Arc<Mutex<vk_mem::Allocator>>。所有内部分配器都使用分配器执行。

dynamic-rendering

如果您想在应用程序中集成库并使用Vulkan的动态渲染,则此功能非常有用。启用后,通常以vk::RenderPass作为参数的函数现在将接受一个DynamicRendering,其中包含UI将被绘制到的颜色附件的格式以及可选的深度附件格式。

集成

您可以在示例的common模块中找到与winit集成的示例。

// Example with default allocator
let renderer = Renderer::with_default_allocator(
    &vk_instance,
    vk_physical_device,
    vk_device.clone(),
    vk_render_pass,
    Options::default(),
).unwrap();

示例

您可以通过运行以下命令来运行一组示例

# If you want to enable validation layers
export VK_LAYER_PATH=$VULKAN_SDK/Bin
export VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation

# Or with Powershell
$env:VK_LAYER_PATH = "$env:VULKAN_SDK\Bin"
$env:VK_INSTANCE_LAYERS = "VK_LAYER_KHRONOS_validation"

# If you changed the shader code (you'll need glslangValidator on you PATH)
# There is also a PowerShell version (compile_shaders.ps1)
./scripts/compile_shaders.sh

# Run an example
cargo run --example <example>

# Example can be one of the following value:
# - demo_windows
# - textures

依赖项

~10–16MB
~225K SLoC