Files
CFDManager/rust/crates/simv-vk/src/shader.rs
T
NotBigGhostandClaude Opus 5 f5c9e61589 Порт редактора SimVulcan на Rust
Та же программа на ash + winit + egui: орбитальная камера, три плоскости сетки,
загрузка .obj, три режима отображения, единый проход динамического рендеринга с
глубинным вложением и submit через synchronization2. Шейдеры общие с C++-версией —
build.rs компилирует их из shaders/ и вшивает SPIR-V в бинарь.

Пять крейтов повторяют карту целей CMake, но инвариант «весь Vulkan в одном месте»
теперь проверяет компилятор: у simv-mesh и simv-editor нет ash в зависимостях.

Расхождения, вынужденные языком, а не вкусом:
 * App переехал в исполняемый крейт — в C++ граф целей цикличен (core владеет vk,
   vk принимает core::Window&), и держится это лишь на том, что simv_vk видит
   заголовки core, не линкуя цель; Cargo такой цикл отвергает;
 * состояние сцены возвращается из замыкания интерфейса, а не ставится сеттерами:
   замыкание вызывается из метода рендерера, трогать рендерер оттуда нельзя;
 * выгрузка меша на видеокарту уехала из середины записи кадра, где C++-версия
   зовёт vkDeviceWaitIdle уже после захвата образа цепочки показа.

Vulkan-контекст и цепочка показа написаны руками: замены vk-bootstrap в экосистеме
Rust нет. Обёртки Buffer и Image, лежащие в C++-версии без применения, здесь
задействованы всеми потребителями.

13 тестов, из них три перенесены из Catch2 дословно. cargo clippy -D warnings чист,
слой валидации молчит.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-30 20:58:19 +03:00

56 lines
2.6 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! Шейдерные модули — перенос `simv::vk::Shader`.
//!
//! Главное отличие от C++-версии: SPIR-V не ищется на диске, а зашит в исполняемый
//! файл на этапе сборки (см. `build.rs`). Вместе с `FindSpvPath` исчезли и
//! POST_BUILD-копирование каталога `spirv/`, и требование запускать редактор из
//! каталога бинаря, и целый класс ошибок «шейдер не найден» во время выполнения:
//! отсутствующий шейдер теперь ломает сборку, а не запуск.
use std::io::Cursor;
use ash::vk;
use crate::error::{Ctx, Result};
/// Скомпилированный SPIR-V, вшитый в бинарь. Пути соответствуют раскладке
/// `shaders/editor/` в корне репозитория.
pub mod spirv {
pub const MESH_VERT: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/editor/mesh.vert.spv"));
pub const MESH_FRAG: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/editor/mesh.frag.spv"));
pub const GRID_VERT: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/editor/grid.vert.spv"));
pub const GRID_FRAG: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/editor/grid.frag.spv"));
}
/// Владеющая обёртка над `VkShaderModule`: уничтожается на выходе из области
/// видимости, в том числе если сборка конвейера завершилась ошибкой.
pub struct ShaderModule {
device: ash::Device,
handle: vk::ShaderModule,
}
impl ShaderModule {
pub fn new(device: &ash::Device, spirv_bytes: &[u8]) -> Result<Self> {
// `read_spv` заодно снимает вопрос выравнивания: `include_bytes!` даёт срез
// байтов, а Vulkan хочет 32-битные слова.
let words = ash::util::read_spv(&mut Cursor::new(spirv_bytes))
.map_err(|e| crate::error::VkError::Other(format!("битый SPIR-V: {e}")))?;
let ci = vk::ShaderModuleCreateInfo::default().code(&words);
let handle =
unsafe { device.create_shader_module(&ci, None) }.ctx("vkCreateShaderModule")?;
Ok(Self {
device: device.clone(),
handle,
})
}
pub fn handle(&self) -> vk::ShaderModule {
self.handle
}
}
impl Drop for ShaderModule {
fn drop(&mut self) {
unsafe { self.device.destroy_shader_module(self.handle, None) };
}
}