Я пытаюсь что-то вычислить с помощью вычислительного шейдера и сохранить результат в образе подкачки, чтобы отобразить его в окне для дальнейшей интерактивности.
Я получаю следующее сообщение об ошибке:
поток 'main' запаниковал в 'вызванном Result::unwrap()
значении Err
: AccessError {error: ImageNotInitialized {требуемый: PresentSrc}, имя_команды: "vkCmdBindDescriptorSets", command_param: "Изображение привязано к дескриптору 0 из набора 0" , command_offset: 1} ', libcore \ result.rs: 1009: 5
примечание: запустить с RUST_BACKTRACE=1
для возврата.
ошибка: процесс не завершился успешно: target\debug\vulkan_test.exe
(код выхода: 101)
main.rs
extern crate vulkano;
extern crate vulkano_shaders;
extern crate vulkano_win;
extern crate winit;
use std::sync::Arc;
use vulkano::command_buffer::AutoCommandBufferBuilder;
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use vulkano::device::{Device, DeviceExtensions};
use vulkano::instance::{Instance, PhysicalDevice};
use vulkano::pipeline::ComputePipeline;
use vulkano::swapchain;
use vulkano::swapchain::{
AcquireError, PresentMode, SurfaceTransform, Swapchain, SwapchainCreationError,
};
use vulkano::sync;
use vulkano::sync::{FlushError, GpuFuture};
use vulkano_win::VkSurfaceBuild;
use winit::{EventsLoop, WindowBuilder};
mod cs {
vulkano_shaders::shader! {
ty: "compute",
// path: "shaders/compute.glsl"
src: "
#version 450
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
layout(set = 0, binding = 0, rgba8) uniform writeonly image2D img;
void main() {
imageStore(img, ivec2(gl_GlobalInvocationID.xy), vec4(1,0,1,1));
}
"
}
}
fn main() {
let instance = {
let extensions = vulkano_win::required_extensions();
Instance::new(None, &extensions, None).expect("failed to create instance")
};
let physical = PhysicalDevice::enumerate(&instance)
.next()
.expect("no device available");
println!("Name: {} (type: {:?})", physical.name(), physical.ty());
println!("Version: {}", physical.api_version());
let mut events_loop = EventsLoop::new();
let surface = WindowBuilder::new()
.with_title("Ray")
.with_dimensions((1600.0, 900.0).into())
.build_vk_surface(&events_loop, instance.clone())
.expect("failed to create window");
let window = surface.window();
let queue_family = physical
.queue_families()
.find(|&q| q.supports_graphics() && surface.is_supported(q).unwrap_or(false))
.expect("failed to create queue family");
let (device, mut queues) = {
let device_ext = DeviceExtensions {
khr_swapchain: true,
..DeviceExtensions::none()
};
Device::new(
physical,
physical.supported_features(),
&device_ext,
[(queue_family, 0.5)].iter().cloned(),
)
.expect("failed to create device")
};
let queue = queues.next().expect("failed to create queue");
let shader = cs::Shader::load(device.clone()).expect("failed to create shader module");
let compute_pipeline = Arc::new(
ComputePipeline::new(device.clone(), &shader.main_entry_point(), &())
.expect("failed to create compute pipeline"),
);
let (mut swapchain, mut images) = {
let caps = surface.capabilities(physical).unwrap();
let usage = caps.supported_usage_flags;
let alpha = caps.supported_composite_alpha.iter().next().unwrap();
let format = caps.supported_formats[0].0;
let initial_dimensions = if let Some(dimensions) = window.get_inner_size() {
let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into();
[dimensions.0, dimensions.1]
} else {
return;
};
Swapchain::new(
device.clone(),
surface.clone(),
caps.min_image_count,
format,
initial_dimensions,
1,
usage,
&queue,
SurfaceTransform::Identity,
alpha,
PresentMode::Fifo,
true,
None,
)
.expect("failed to create swapchain")
};
let mut recreate_swapchain = false;
let mut previous_frame_end = Box::new(sync::now(device.clone())) as Box<GpuFuture>;
loop {
previous_frame_end.cleanup_finished();
if recreate_swapchain {
let dimensions = if let Some(dimensions) = window.get_inner_size() {
let dimensions: (u32, u32) =
dimensions.to_physical(window.get_hidpi_factor()).into();
[dimensions.0, dimensions.1]
} else {
return;
};
let (new_swapchain, new_images) = match swapchain.recreate_with_dimension(dimensions) {
Ok(r) => r,
Err(SwapchainCreationError::UnsupportedDimensions) => continue,
Err(err) => panic!("{:?}", err),
};
swapchain = new_swapchain;
images = new_images;
recreate_swapchain = false;
}
let (image_index, acquire_future) =
match swapchain::acquire_next_image(swapchain.clone(), None) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
recreate_swapchain = true;
continue;
}
Err(err) => panic!("{:?}", err),
};
let command_buffer = {
let set = Arc::new(
PersistentDescriptorSet::start(compute_pipeline.clone(), 0)
.add_image(images[image_index].clone())
.unwrap()
.build()
.unwrap(),
);
AutoCommandBufferBuilder::new(device.clone(), queue.family())
.unwrap()
.dispatch([200, 100, 1], compute_pipeline.clone(), set.clone(), ())
.unwrap()
.build()
.unwrap()
};
let future = previous_frame_end
.join(acquire_future)
.then_execute(queue.clone(), command_buffer)
.unwrap()
.then_swapchain_present(queue.clone(), swapchain.clone(), image_index)
.then_signal_fence_and_flush();
match future {
Ok(future) => {
previous_frame_end = Box::new(future) as Box<_>;
}
Err(FlushError::OutOfDate) => {
recreate_swapchain = true;
previous_frame_end = Box::new(sync::now(device.clone())) as Box<_>;
}
Err(e) => {
println!("{:?}", e);
previous_frame_end = Box::new(sync::now(device.clone())) as Box<_>;
}
}
let mut done = false;
events_loop.poll_events(|ev| match ev {
winit::Event::WindowEvent { event, .. } => match event {
winit::WindowEvent::CloseRequested => done = true,
winit::WindowEvent::KeyboardInput {
input:
winit::KeyboardInput {
virtual_keycode: Some(virtual_code),
state: winit::ElementState::Released,
..
},
..
} => match virtual_code {
winit::VirtualKeyCode::Escape => done = true,
_ => (),
},
winit::WindowEvent::Resized(_) => recreate_swapchain = true,
_ => (),
},
_ => (),
});
if done {
return;
}
}
}
Полная ошибка возврата
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: AccessError { error: ImageNotInitialized { requested: PresentSrc }, command_name: "vkCmdBindDescriptorSets", command_param: "Image bound to descriptor 0 of set 0", command_offset: 1 }', libcore\result.rs:1009:5
stack backtrace:
0: std::sys::windows::backtrace::set_frames
at /rustc/b6c32da9b0481e3e9d737153286b3ff8aa39a22c\src/libstd\sys\windows\backtrace\mod.rs:104
1: std::sys::windows::backtrace::set_frames
at /rustc/b6c32da9b0481e3e9d737153286b3ff8aa39a22c\src/libstd\sys\windows\backtrace\mod.rs:104
2: std::sys_common::backtrace::_print
at /rustc/b6c32da9b0481e3e9d737153286b3ff8aa39a22c\src/libstd\sys_common\backtrace.rs:71
3: std::sys_common::backtrace::_print
at /rustc/b6c32da9b0481e3e9d737153286b3ff8aa39a22c\src/libstd\sys_common\backtrace.rs:71
4: std::panicking::default_hook::{{closure}}
at /rustc/b6c32da9b0481e3e9d737153286b3ff8aa39a22c\src/libstd\panicking.rs:211
5: std::panicking::default_hook
at /rustc/b6c32da9b0481e3e9d737153286b3ff8aa39a22c\src/libstd\panicking.rs:227
6: std::panicking::rust_panic_with_hook
at /rustc/b6c32da9b0481e3e9d737153286b3ff8aa39a22c\src/libstd\panicking.rs:476
7: std::panicking::continue_panic_fmt
at /rustc/b6c32da9b0481e3e9d737153286b3ff8aa39a22c\src/libstd\panicking.rs:390
8: std::panicking::rust_begin_panic
at /rustc/b6c32da9b0481e3e9d737153286b3ff8aa39a22c\src/libstd\panicking.rs:325
9: core::panicking::panic_fmt
at /rustc/b6c32da9b0481e3e9d737153286b3ff8aa39a22c\src/libcore\panicking.rs:77
10: core::result::unwrap_failed<vulkano::command_buffer::traits::CommandBufferExecError>
at \libcore\macros.rs:26
11: core::result::Result<vulkano::command_buffer::traits::CommandBufferExecFuture<vulkano::sync::future::join::JoinFuture<alloc::boxed::Box<GpuFuture>, vulkano::swapchain::swapchain::SwapchainAcquireFuture<winit::Window>>, vulkano::command_buffer::auto::AutoCommandBuffer<vulkano::command_buffer::pool::standard::StandardCommandPoolAlloc>>, vulkano::command_buffer::traits::CommandBufferExecError>::unwrap<vulkano::command_buffer::traits::CommandBufferExecFuture<vulkano::sync::future::join::JoinFuture<alloc::boxed::Box<GpuFuture>, vulkano::swapchain::swapchain::SwapchainAcquireFuture<winit::Window>>, vulkano::command_buffer::auto::AutoCommandBuffer<vulkano::command_buffer::pool::standard::StandardCommandPoolAlloc>>,vulkano::command_buffer::traits::CommandBufferExecError>
at \libcore\result.rs:808
12: vulkan_test::main
at .\src\main.rs:178
13: std::rt::lang_start::{{closure}}<()>
at \libstd\rt.rs:74
14: std::rt::lang_start_internal::{{closure}}
at /rustc/b6c32da9b0481e3e9d737153286b3ff8aa39a22c\src/libstd\rt.rs:59
15: std::rt::lang_start_internal::{{closure}}
at /rustc/b6c32da9b0481e3e9d737153286b3ff8aa39a22c\src/libstd\rt.rs:59
16: panic_unwind::__rust_maybe_catch_panic
at /rustc/b6c32da9b0481e3e9d737153286b3ff8aa39a22c\src/libpanic_unwind\lib.rs:102
17: std::panicking::try
at /rustc/b6c32da9b0481e3e9d737153286b3ff8aa39a22c\src/libstd\panicking.rs:289
18: std::panicking::try
at /rustc/b6c32da9b0481e3e9d737153286b3ff8aa39a22c\src/libstd\panicking.rs:289
19: std::panicking::try
at /rustc/b6c32da9b0481e3e9d737153286b3ff8aa39a22c\src/libstd\panicking.rs:289
20: std::rt::lang_start<()>
at \libstd\rt.rs:74
21: main
22: invoke_main
at d:\agent\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
23: invoke_main
at d:\agent\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
24: BaseThreadInitThunk
25: RtlUserThreadStart