Vulkan Tutorial의 Rust 버전을 해 보았다 ~ 준비편 ~

11735 단어 Vulkan입문Rust
Vulkan의 입문을 Rust로 해 나갑니다. 목차는 이쪽 . 이번까지의 구현을 했다 GitHub는 이쪽 .

Vulkan 개요



Vulkan은 응용 프로그램별로 Instance를 만들고 각 물리적 장치에 해당하는 LoaderLayer를로드하고 Layer를 통해 각 드라이버를 처리합니다.
Vulkanアーキテクチャの基本
(이미지는 h tps:///ゔヵ.ぅ나 rg. 이 m/도 c/sdk/1.2.131.2/ぃないx/개별 l/html/01-아니 t_인 s단세. HTML에서 인용)
또 그릴 때는, 묘화 명령용의 Queue나 각 OS 고유의 윈도우와 묘화처의 Surface 를 작성해, 렌더 패스를 작성해, 파이프라인을 구축해, Queue 할 수 있습니다.

Vulkan으로 그릴 때까지 준비



이번에는 준비편으로서 디바이스(GPU)를 취득할 때까지를 씁니다.

개발 환경 준비


  • Vulkan 라이브러리 기타 설치
  • 적절한 디렉토리에서 cargo new [プロジェクト名] 를 사용하여 Rust 프로젝트를 만듭니다
  • Vulkan의 Rust 래퍼 인 VulkanoCargo.toml에 추가

  • Validation layers 추가



    현재는 상관없지만, Validation layers는 부정한 값이 GPU측에 넘지 않도록 감시하는 등이 있기 때문에, 이 단계부터 디버그시에만 유효하게 해 둡니다.

    레이어 열거



    레이어를 유효하게 하려면 Instance 의 작성시에 인수에 레이어명을 건네줄 필요가 있으므로, 그 전에 레이어를 열거해 이름을 확인해 봅니다.
    vulkano::instance::layers_list().unwrap().for_each(|layer| ...);
    

    열거된 이름으로부터, 이번은 VK_LAYER_LUNARG_standard_validationVK_LAYER_KHRONOS_validation 를 읽어 봅니다.

    Layer가 지원되는지 확인



    위에서 먼저 Layer를 열거 한 다음 Layer 그냥 추출합니다.
    let validation_layers = [
        "VK_LAYER_LUNARG_standard_validation",
        "VK_LAYER_KHRONOS_validation",
    ];
    let supported_validation_layers: Vec<_> = layers_list()
        .unwrap()
        .filter(|layer| validation_layers.contains(&layer.name()))
        .collect();
    

    레이어 사용



    디버그 정보등을 취득할 수 있게 되므로, Layer 를 유효하게 합니다. Vulkano에서는 이러한 extensions는 VK_EXT_debug_utils 의 작성시에 인수로 건네주므로, 우선 무엇을 유효하게 할까라고 하는 설정을 해 둡니다.
    let extensions = InstanceExtensions {
        ext_debug_utils: true,
        ..InstanceExtensions::supported_by_core().unwrap()
    };
    
    VK_EXT_debug_utils로 설정하면 Instance가 활성화됩니다.

    ext_debug_utils: true 만들기



    응용 프로그램별로 준비해야 하는 VK_EXT_debug_utils를 만듭니다.
    let instance = Instance::new(
        Some(&app_info_from_cargo_toml!()),
        &extensions,
        supported_validation_layers.iter().map(|layer| layer.name()),
    )
    .expect("Could not build a Vulkan instance");
    

    여기에서는 그대로 쓰고 있습니다만, Validation layers를 디버그시만 유효하게 하기 위해서 Instance 등으로 분기시켜 주세요.

    vulkano::instance::Instance 설정



    기본적으로 Validation layers는 표준 출력에 정보를 써 갑니다만, 어느 레벨의 정보를 쓰는지 등 세세한 설정을 하기 위해서는 콜백을 작성할 필요가 있습니다.
    DebugCallback::new(&instance, severity, ty, |message| ...).ok();
    

    주의점으로서 cfg!(debug_assertions) 로 두지 않으면 DebugCallbackext_debug_utils: true 를 돌려줍니다.

    물리적 디바이스 획득



    물리적 디바이스 열거



    물리적 장치는 DebugCallback::new로 표시되며 Err로 열거할 수 있습니다.
    PhysicalDevice::enumerate(&instance).for_each(|device| ...);
    

    GPU 획득



    열거된 물리 디바이스 중 그래픽용 vulkano::instance::PhysicalDevice 를 가지는 디바이스가 필요하기 때문에, 여기에서는 최초로 발견된 그래픽용 PhysicalDevice::enumerate 를 가지고 있는 디바이스를 취득합니다. 참고원 사이트 그리고 그 Rust 버전 그렇다면 조금 번거로운 느낌입니다만, 이하와 같이 쓰면 똑같이 동작할 것입니다.
    let device = PhysicalDevice::enumerate(&instance)
        .filter(|device| {
            device
                .queue_families()
                .any(|queue_family| queue_family.supports_graphics())
        })
        .next()
        .expect("Could not find any GPU");
    

    논리 장치 얻기



    위에서 얻은 GPU에서 해당 논리 장치를 가져옵니다.
    let (_device, _queues) = PhysicalDevice::enumerate(&instance)
        .filter_map(|device| {
            device
                .queue_families()
                .filter(|queue_family| queue_family.supports_graphics())
                .map(|queue_family| (device, queue_family))
                .next()
        })
        .filter_map(|(device, queue_family)| {
            Device::new(
                device,
                &Features::none(),
                &DeviceExtensions::supported_by_device(device),
                vec![(queue_family, 1.0)],
            )
            .ok()
        })
        .next()
        .expect("Could not find any GPU");
    

    여기까지 드디어 준비가 된 형태입니다.

    정리와 감상



    이 단계라면 아직 Queue 등 잘 모르는 곳도 많습니다만, 최저한 Vulkan이 움직이고 있는 것의 확인은 할 수 있었습니다. 또, Vulkano 덕분에 원래의 Vulkan보다 오이타 기술이 편하다고 생각합니다. 감사합니다 Rust. 감사합니다 Vulkano.

    좋은 웹페이지 즐겨찾기