- Replace gpu-allocator with vk-mem 0.5.0 (VMA 3.3.0) in renderer_device - Add public GpuAllocation wrapper, MemoryLocation, AllocationDesc, and allocate_for_buffer/image + bind_buffer/image_memory helpers - Restrict CPU-mapped allocations to HOST_VISIBLE|HOST_COHERENT memory types - Handle guards: raw buffer/image handles owned before allocation so failure paths never leak - Use renderer_device::device::MemoryLocation across renderer, renderer_resources, and renderer_rendergraph; remove all gpu-allocator dependencies - Error on dedicated allocation below Vulkan 1.1 instead of silent downgrade - Add Send/Sync asserts, coherent-mapping and dedicated-allocation validation tests; update AGENTS.md docs
94 lines
3.1 KiB
Rust
94 lines
3.1 KiB
Rust
use std::sync::Arc;
|
|
|
|
use ash::vk;
|
|
use renderer_device::{
|
|
device::{MemoryLocation, QueueFlags},
|
|
testing::TestVulkan,
|
|
};
|
|
use renderer_rendergraph::{
|
|
RenderGraph,
|
|
commands::CopyBuffer,
|
|
recorder::CommandRecorder,
|
|
resources::{BufferRange, ResourceState},
|
|
};
|
|
use renderer_resources::buffers::{Buffer, BufferDesc};
|
|
|
|
#[test]
|
|
fn imported_buffer_copy_records_under_validation() {
|
|
let Some(test) = TestVulkan::acquire() else {
|
|
return;
|
|
};
|
|
let device = test.device();
|
|
if device.enabled_features().core13.synchronization2 != vk::TRUE {
|
|
eprintln!("Skipping graph recording: synchronization2 is unsupported");
|
|
return;
|
|
}
|
|
let make_buffer = || {
|
|
Arc::new(
|
|
Buffer::new(
|
|
device.clone(),
|
|
BufferDesc {
|
|
size: 256,
|
|
usage: vk::BufferUsageFlags::TRANSFER_SRC | vk::BufferUsageFlags::TRANSFER_DST,
|
|
queue_families: QueueFlags::empty(),
|
|
mem_location: MemoryLocation::CpuToGpu,
|
|
..Default::default()
|
|
},
|
|
)
|
|
.expect("create graph test buffer"),
|
|
)
|
|
};
|
|
let source = make_buffer();
|
|
let destination = make_buffer();
|
|
let mut graph = RenderGraph::new();
|
|
let source_id = graph
|
|
.import_buffer(source, ResourceState::default())
|
|
.expect("import source buffer");
|
|
let destination_id = graph
|
|
.import_buffer(destination, ResourceState::default())
|
|
.expect("import destination buffer");
|
|
graph.push(CopyBuffer {
|
|
src: source_id,
|
|
src_range: BufferRange {
|
|
offset: 0,
|
|
size: 256,
|
|
},
|
|
dst: destination_id,
|
|
dst_range: BufferRange {
|
|
offset: 0,
|
|
size: 256,
|
|
},
|
|
});
|
|
let mut graph = graph.compile().expect("compile imported buffer graph");
|
|
|
|
let pool_info = vk::CommandPoolCreateInfo::default()
|
|
.queue_family_index(device.queues.graphics().family.index.index());
|
|
let pool = unsafe { device.dev().create_command_pool(&pool_info, None) }
|
|
.expect("create graph command pool");
|
|
let allocation_info = vk::CommandBufferAllocateInfo::default()
|
|
.command_pool(pool)
|
|
.level(vk::CommandBufferLevel::PRIMARY)
|
|
.command_buffer_count(1);
|
|
let command_buffer = unsafe { device.dev().allocate_command_buffers(&allocation_info) }
|
|
.expect("allocate graph command buffer")[0];
|
|
unsafe {
|
|
device
|
|
.dev()
|
|
.begin_command_buffer(command_buffer, &vk::CommandBufferBeginInfo::default())
|
|
.expect("begin graph command buffer");
|
|
}
|
|
let mut recorder = CommandRecorder::new(device.dev(), command_buffer);
|
|
graph
|
|
.record_commands(&mut recorder)
|
|
.expect("record imported buffer graph");
|
|
unsafe {
|
|
device
|
|
.dev()
|
|
.end_command_buffer(command_buffer)
|
|
.expect("end graph command buffer");
|
|
device.dev().destroy_command_pool(pool, None);
|
|
}
|
|
device.wait_idle().expect("wait for graph device idle");
|
|
test.assert_no_validation_errors();
|
|
}
|