mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-25 16:25:31 +00:00
Better custom vertex buffer layouts support (#2119)
* Implement VertexDefinition for VertexBufferInfo, change Vertex signature to return VertexInfo and implement VertexInput-trait helper for Vertex to construct VertexBufferInfo objects from Vertex types. Updated teapot example to show usage. * Reimplement BuffersDefinition leveraging VertexBufferInfo * Reduce the amount of types required, remove VertexInfo, expose VertexBufferInfo methods on Vertex and use std HashMap transparently instead. * Fix teapot example * Fix outdated docs and use full path to Vertex trait to avoid issues * Fix formatting of imports * Remove clone and directly instantiate VertexInputBindingDescription. * Rename VertexBufferInfo to VertexBufferDescription and being update of examples to use it * Run cargo clippy fix to cleanup imports in examples * Remove obsolete comment * cargo fmt
This commit is contained in:
parent
21f850dc99
commit
834cc1eea5
@ -33,7 +33,7 @@ use vulkano::{
|
||||
pipeline::{
|
||||
graphics::{
|
||||
input_assembly::InputAssemblyState,
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline,
|
||||
@ -225,7 +225,7 @@ fn main() {
|
||||
.unwrap();
|
||||
|
||||
let pipeline = GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<Vertex>())
|
||||
.vertex_input_state(Vertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.input_assembly_state(InputAssemblyState::new())
|
||||
.viewport_state(ViewportState::viewport_dynamic_scissor_irrelevant())
|
||||
@ -277,7 +277,7 @@ fn main() {
|
||||
}) {
|
||||
Ok(r) => r,
|
||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
||||
Err(e) => panic!("Failed to recreate swapchain: {:?}", e),
|
||||
Err(e) => panic!("Failed to recreate swapchain: {e:?}"),
|
||||
};
|
||||
|
||||
swapchain = new_swapchain;
|
||||
@ -296,7 +296,7 @@ fn main() {
|
||||
recreate_swapchain = true;
|
||||
return;
|
||||
}
|
||||
Err(e) => panic!("Failed to acquire next image: {:?}", e),
|
||||
Err(e) => panic!("Failed to acquire next image: {e:?}"),
|
||||
};
|
||||
|
||||
if suboptimal {
|
||||
@ -385,7 +385,7 @@ fn main() {
|
||||
previous_frame_end = Some(Box::new(sync::now(device.clone())) as Box<_>);
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to flush future: {:?}", e);
|
||||
println!("Failed to flush future: {e:?}");
|
||||
previous_frame_end = Some(Box::new(sync::now(device.clone())) as Box<_>);
|
||||
}
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ fn main() {
|
||||
}) {
|
||||
Ok(r) => r,
|
||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
||||
Err(e) => panic!("Failed to recreate swapchain: {:?}", e),
|
||||
Err(e) => panic!("Failed to recreate swapchain: {e:?}"),
|
||||
};
|
||||
|
||||
swapchain = new_swapchain;
|
||||
@ -209,7 +209,7 @@ fn main() {
|
||||
recreate_swapchain = true;
|
||||
return;
|
||||
}
|
||||
Err(e) => panic!("Failed to acquire next image: {:?}", e),
|
||||
Err(e) => panic!("Failed to acquire next image: {e:?}"),
|
||||
};
|
||||
|
||||
if suboptimal {
|
||||
@ -289,7 +289,7 @@ fn main() {
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to flush future: {:?}", e);
|
||||
println!("Failed to flush future: {e:?}");
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ use vulkano::{
|
||||
graphics::{
|
||||
color_blend::{AttachmentBlend, BlendFactor, BlendOp, ColorBlendState},
|
||||
input_assembly::InputAssemblyState,
|
||||
vertex_input::BuffersDefinition,
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline, Pipeline, PipelineBindPoint,
|
||||
@ -81,7 +81,7 @@ impl AmbientLightingSystem {
|
||||
let fs = fs::load(gfx_queue.device().clone()).expect("failed to create shader module");
|
||||
|
||||
GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<LightingVertex>())
|
||||
.vertex_input_state(LightingVertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.input_assembly_state(InputAssemblyState::new())
|
||||
.viewport_state(ViewportState::viewport_dynamic_scissor_irrelevant())
|
||||
|
@ -25,7 +25,7 @@ use vulkano::{
|
||||
graphics::{
|
||||
color_blend::{AttachmentBlend, BlendFactor, BlendOp, ColorBlendState},
|
||||
input_assembly::InputAssemblyState,
|
||||
vertex_input::BuffersDefinition,
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline, Pipeline, PipelineBindPoint,
|
||||
@ -82,7 +82,7 @@ impl DirectionalLightingSystem {
|
||||
let fs = fs::load(gfx_queue.device().clone()).expect("failed to create shader module");
|
||||
|
||||
GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<LightingVertex>())
|
||||
.vertex_input_state(LightingVertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.input_assembly_state(InputAssemblyState::new())
|
||||
.viewport_state(ViewportState::viewport_dynamic_scissor_irrelevant())
|
||||
|
@ -25,7 +25,7 @@ use vulkano::{
|
||||
graphics::{
|
||||
color_blend::{AttachmentBlend, BlendFactor, BlendOp, ColorBlendState},
|
||||
input_assembly::InputAssemblyState,
|
||||
vertex_input::BuffersDefinition,
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline, Pipeline, PipelineBindPoint,
|
||||
@ -81,7 +81,7 @@ impl PointLightingSystem {
|
||||
let fs = fs::load(gfx_queue.device().clone()).expect("failed to create shader module");
|
||||
|
||||
GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<LightingVertex>())
|
||||
.vertex_input_state(LightingVertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.input_assembly_state(InputAssemblyState::new())
|
||||
.viewport_state(ViewportState::viewport_dynamic_scissor_irrelevant())
|
||||
|
@ -216,7 +216,7 @@ fn main() {
|
||||
}) {
|
||||
Ok(r) => r,
|
||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
||||
Err(e) => panic!("Failed to recreate swapchain: {:?}", e),
|
||||
Err(e) => panic!("Failed to recreate swapchain: {e:?}"),
|
||||
};
|
||||
let new_images = new_images
|
||||
.into_iter()
|
||||
@ -235,7 +235,7 @@ fn main() {
|
||||
recreate_swapchain = true;
|
||||
return;
|
||||
}
|
||||
Err(e) => panic!("Failed to acquire next image: {:?}", e),
|
||||
Err(e) => panic!("Failed to acquire next image: {e:?}"),
|
||||
};
|
||||
|
||||
if suboptimal {
|
||||
@ -285,7 +285,7 @@ fn main() {
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to flush future: {:?}", e);
|
||||
println!("Failed to flush future: {e:?}");
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ use vulkano::{
|
||||
graphics::{
|
||||
depth_stencil::DepthStencilState,
|
||||
input_assembly::InputAssemblyState,
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline,
|
||||
@ -71,7 +71,7 @@ impl TriangleDrawSystem {
|
||||
let fs = fs::load(gfx_queue.device().clone()).expect("failed to create shader module");
|
||||
|
||||
GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<TriangleVertex>())
|
||||
.vertex_input_state(TriangleVertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.input_assembly_state(InputAssemblyState::new())
|
||||
.viewport_state(ViewportState::viewport_dynamic_scissor_irrelevant())
|
||||
|
@ -146,11 +146,8 @@ fn main() {
|
||||
.physical_device()
|
||||
.properties()
|
||||
.min_uniform_buffer_offset_alignment as usize;
|
||||
println!(
|
||||
"Minimum uniform buffer offset alignment: {}",
|
||||
min_dynamic_align
|
||||
);
|
||||
println!("Input: {:?}", data);
|
||||
println!("Minimum uniform buffer offset alignment: {min_dynamic_align}");
|
||||
println!("Input: {data:?}");
|
||||
// Round size up to the next multiple of align.
|
||||
let align = (size_of::<u32>() + min_dynamic_align - 1) & !(min_dynamic_align - 1);
|
||||
let aligned_data = {
|
||||
|
@ -166,7 +166,7 @@ fn main() {
|
||||
// local size can lead to significant performance penalty.
|
||||
let (local_size_x, local_size_y) = match device.physical_device().properties().subgroup_size {
|
||||
Some(subgroup_size) => {
|
||||
println!("Subgroup size is {}", subgroup_size);
|
||||
println!("Subgroup size is {subgroup_size}");
|
||||
|
||||
// Most of the subgroup values are divisors of 8
|
||||
(8, subgroup_size / 8)
|
||||
@ -179,10 +179,7 @@ fn main() {
|
||||
}
|
||||
};
|
||||
|
||||
println!(
|
||||
"Local size will be set to: ({}, {}, 1)",
|
||||
local_size_x, local_size_y
|
||||
);
|
||||
println!("Local size will be set to: ({local_size_x}, {local_size_y}, 1)");
|
||||
|
||||
let spec_consts = cs::SpecializationConstants {
|
||||
red: 0.2,
|
||||
|
@ -39,7 +39,7 @@ mod linux {
|
||||
graphics::{
|
||||
color_blend::ColorBlendState,
|
||||
input_assembly::{InputAssemblyState, PrimitiveTopology},
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Scissor, Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline, Pipeline, PipelineBindPoint,
|
||||
@ -293,7 +293,7 @@ mod linux {
|
||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => {
|
||||
return
|
||||
}
|
||||
Err(e) => panic!("Failed to recreate swapchain: {:?}", e),
|
||||
Err(e) => panic!("Failed to recreate swapchain: {e:?}"),
|
||||
};
|
||||
|
||||
swapchain = new_swapchain;
|
||||
@ -312,7 +312,7 @@ mod linux {
|
||||
recreate_swapchain = true;
|
||||
return;
|
||||
}
|
||||
Err(e) => panic!("Failed to acquire next image: {:?}", e),
|
||||
Err(e) => panic!("Failed to acquire next image: {e:?}"),
|
||||
};
|
||||
|
||||
if suboptimal {
|
||||
@ -375,7 +375,7 @@ mod linux {
|
||||
previous_frame_end = Some(vulkano::sync::now(device.clone()).boxed());
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to flush future: {:?}", e);
|
||||
println!("Failed to flush future: {e:?}");
|
||||
previous_frame_end = Some(vulkano::sync::now(device.clone()).boxed());
|
||||
}
|
||||
};
|
||||
@ -608,7 +608,7 @@ mod linux {
|
||||
let subpass = Subpass::from(render_pass.clone(), 0).unwrap();
|
||||
|
||||
let pipeline = GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<MyVertex>())
|
||||
.vertex_input_state(MyVertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.input_assembly_state(
|
||||
InputAssemblyState::new().topology(PrimitiveTopology::TriangleStrip),
|
||||
|
@ -35,7 +35,7 @@ use vulkano::{
|
||||
graphics::{
|
||||
color_blend::ColorBlendState,
|
||||
input_assembly::{InputAssemblyState, PrimitiveTopology},
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline, Pipeline, PipelineBindPoint,
|
||||
@ -326,7 +326,7 @@ fn main() {
|
||||
|
||||
let subpass = Subpass::from(render_pass.clone(), 0).unwrap();
|
||||
let pipeline = GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<Vertex>())
|
||||
.vertex_input_state(Vertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.input_assembly_state(InputAssemblyState::new().topology(PrimitiveTopology::TriangleStrip))
|
||||
.viewport_state(ViewportState::viewport_dynamic_scissor_irrelevant())
|
||||
@ -390,7 +390,7 @@ fn main() {
|
||||
}) {
|
||||
Ok(r) => r,
|
||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
||||
Err(e) => panic!("Failed to recreate swapchain: {:?}", e),
|
||||
Err(e) => panic!("Failed to recreate swapchain: {e:?}"),
|
||||
};
|
||||
|
||||
swapchain = new_swapchain;
|
||||
@ -406,7 +406,7 @@ fn main() {
|
||||
recreate_swapchain = true;
|
||||
return;
|
||||
}
|
||||
Err(e) => panic!("Failed to acquire next image: {:?}", e),
|
||||
Err(e) => panic!("Failed to acquire next image: {e:?}"),
|
||||
};
|
||||
|
||||
if suboptimal {
|
||||
@ -466,7 +466,7 @@ fn main() {
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to flush future: {:?}", e);
|
||||
println!("Failed to flush future: {e:?}");
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ use vulkano::{
|
||||
graphics::{
|
||||
color_blend::ColorBlendState,
|
||||
input_assembly::{InputAssemblyState, PrimitiveTopology},
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline, Pipeline, PipelineBindPoint,
|
||||
@ -257,7 +257,7 @@ fn main() {
|
||||
|
||||
let subpass = Subpass::from(render_pass.clone(), 0).unwrap();
|
||||
let pipeline = GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<Vertex>())
|
||||
.vertex_input_state(Vertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.input_assembly_state(InputAssemblyState::new().topology(PrimitiveTopology::TriangleStrip))
|
||||
.viewport_state(ViewportState::viewport_dynamic_scissor_irrelevant())
|
||||
@ -321,7 +321,7 @@ fn main() {
|
||||
}) {
|
||||
Ok(r) => r,
|
||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
||||
Err(e) => panic!("Failed to recreate swapchain: {:?}", e),
|
||||
Err(e) => panic!("Failed to recreate swapchain: {e:?}"),
|
||||
};
|
||||
|
||||
swapchain = new_swapchain;
|
||||
@ -337,7 +337,7 @@ fn main() {
|
||||
recreate_swapchain = true;
|
||||
return;
|
||||
}
|
||||
Err(e) => panic!("Failed to acquire next image: {:?}", e),
|
||||
Err(e) => panic!("Failed to acquire next image: {e:?}"),
|
||||
};
|
||||
|
||||
if suboptimal {
|
||||
@ -397,7 +397,7 @@ fn main() {
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to flush future: {:?}", e);
|
||||
println!("Failed to flush future: {e:?}");
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ use vulkano::{
|
||||
graphics::{
|
||||
color_blend::ColorBlendState,
|
||||
input_assembly::{InputAssemblyState, PrimitiveTopology},
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline, Pipeline, PipelineBindPoint,
|
||||
@ -263,7 +263,7 @@ fn main() {
|
||||
|
||||
let subpass = Subpass::from(render_pass.clone(), 0).unwrap();
|
||||
let pipeline = GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<Vertex>())
|
||||
.vertex_input_state(Vertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.input_assembly_state(InputAssemblyState::new().topology(PrimitiveTopology::TriangleStrip))
|
||||
.viewport_state(ViewportState::viewport_dynamic_scissor_irrelevant())
|
||||
@ -334,7 +334,7 @@ fn main() {
|
||||
}) {
|
||||
Ok(r) => r,
|
||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
||||
Err(e) => panic!("Failed to recreate swapchain: {:?}", e),
|
||||
Err(e) => panic!("Failed to recreate swapchain: {e:?}"),
|
||||
};
|
||||
|
||||
swapchain = new_swapchain;
|
||||
@ -350,7 +350,7 @@ fn main() {
|
||||
recreate_swapchain = true;
|
||||
return;
|
||||
}
|
||||
Err(e) => panic!("Failed to acquire next image: {:?}", e),
|
||||
Err(e) => panic!("Failed to acquire next image: {e:?}"),
|
||||
};
|
||||
|
||||
if suboptimal {
|
||||
@ -410,7 +410,7 @@ fn main() {
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to flush future: {:?}", e);
|
||||
println!("Failed to flush future: {e:?}");
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ use vulkano::{
|
||||
pipeline::{
|
||||
graphics::{
|
||||
input_assembly::InputAssemblyState,
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
ComputePipeline, GraphicsPipeline, Pipeline, PipelineBindPoint,
|
||||
@ -302,7 +302,7 @@ fn main() {
|
||||
}
|
||||
|
||||
let render_pipeline = GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<Vertex>())
|
||||
.vertex_input_state(Vertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.input_assembly_state(InputAssemblyState::new())
|
||||
.viewport_state(ViewportState::viewport_dynamic_scissor_irrelevant())
|
||||
@ -355,7 +355,7 @@ fn main() {
|
||||
}) {
|
||||
Ok(r) => r,
|
||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
||||
Err(e) => panic!("Failed to recreate swapchain: {:?}", e),
|
||||
Err(e) => panic!("Failed to recreate swapchain: {e:?}"),
|
||||
};
|
||||
|
||||
swapchain = new_swapchain;
|
||||
@ -374,7 +374,7 @@ fn main() {
|
||||
recreate_swapchain = true;
|
||||
return;
|
||||
}
|
||||
Err(e) => panic!("Failed to acquire next image: {:?}", e),
|
||||
Err(e) => panic!("Failed to acquire next image: {e:?}"),
|
||||
};
|
||||
|
||||
if suboptimal {
|
||||
@ -470,7 +470,7 @@ fn main() {
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to flush future: {:?}", e);
|
||||
println!("Failed to flush future: {e:?}");
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ use vulkano::{
|
||||
pipeline::{
|
||||
graphics::{
|
||||
input_assembly::InputAssemblyState,
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline,
|
||||
@ -290,11 +290,7 @@ fn main() {
|
||||
let pipeline = GraphicsPipeline::start()
|
||||
// Use the `BuffersDefinition` to describe to vulkano how the two vertex types
|
||||
// are expected to be used.
|
||||
.vertex_input_state(
|
||||
BuffersDefinition::new()
|
||||
.vertex::<TriangleVertex>()
|
||||
.instance::<InstanceData>(),
|
||||
)
|
||||
.vertex_input_state([TriangleVertex::per_vertex(), InstanceData::per_instance()])
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.input_assembly_state(InputAssemblyState::new())
|
||||
.viewport_state(ViewportState::viewport_dynamic_scissor_irrelevant())
|
||||
@ -346,7 +342,7 @@ fn main() {
|
||||
}) {
|
||||
Ok(r) => r,
|
||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
||||
Err(e) => panic!("Failed to recreate swapchain: {:?}", e),
|
||||
Err(e) => panic!("Failed to recreate swapchain: {e:?}"),
|
||||
};
|
||||
|
||||
swapchain = new_swapchain;
|
||||
@ -365,7 +361,7 @@ fn main() {
|
||||
recreate_swapchain = true;
|
||||
return;
|
||||
}
|
||||
Err(e) => panic!("Failed to acquire next image: {:?}", e),
|
||||
Err(e) => panic!("Failed to acquire next image: {e:?}"),
|
||||
};
|
||||
|
||||
if suboptimal {
|
||||
@ -425,7 +421,7 @@ fn main() {
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to flush future: {:?}", e);
|
||||
println!("Failed to flush future: {e:?}");
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ fn compute_then_render(
|
||||
// Start frame
|
||||
let before_pipeline_future = match renderer.acquire() {
|
||||
Err(e) => {
|
||||
println!("{}", e);
|
||||
println!("{e}");
|
||||
return;
|
||||
}
|
||||
Ok(future) => future,
|
||||
|
@ -24,7 +24,7 @@ use vulkano::{
|
||||
pipeline::{
|
||||
graphics::{
|
||||
input_assembly::InputAssemblyState,
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline, Pipeline, PipelineBindPoint,
|
||||
@ -106,7 +106,7 @@ impl PixelsDrawPipeline {
|
||||
let vs = vs::load(gfx_queue.device().clone()).expect("failed to create shader module");
|
||||
let fs = fs::load(gfx_queue.device().clone()).expect("failed to create shader module");
|
||||
GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<TexturedVertex>())
|
||||
.vertex_input_state(TexturedVertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.input_assembly_state(InputAssemblyState::new())
|
||||
.fragment_shader(fs.entry_point("main").unwrap(), ())
|
||||
|
@ -83,7 +83,7 @@ use vulkano::{
|
||||
pipeline::{
|
||||
graphics::{
|
||||
multisample::MultisampleState,
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline,
|
||||
@ -296,7 +296,7 @@ fn main() {
|
||||
|
||||
let subpass = Subpass::from(render_pass, 0).unwrap();
|
||||
let pipeline = GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<Vertex>())
|
||||
.vertex_input_state(Vertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.viewport_state(ViewportState::viewport_dynamic_scissor_irrelevant())
|
||||
.fragment_shader(fs.entry_point("main").unwrap(), ())
|
||||
|
@ -34,7 +34,7 @@ use vulkano::{
|
||||
pipeline::{
|
||||
graphics::{
|
||||
input_assembly::InputAssemblyState,
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline,
|
||||
@ -257,7 +257,7 @@ fn main() {
|
||||
.unwrap();
|
||||
|
||||
let pipeline = GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<Vertex>())
|
||||
.vertex_input_state(Vertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.input_assembly_state(InputAssemblyState::new())
|
||||
.viewport_state(ViewportState::viewport_dynamic_scissor_irrelevant())
|
||||
@ -399,7 +399,7 @@ fn main() {
|
||||
}) {
|
||||
Ok(r) => r,
|
||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
||||
Err(e) => panic!("Failed to recreate swapchain: {:?}", e),
|
||||
Err(e) => panic!("Failed to recreate swapchain: {e:?}"),
|
||||
};
|
||||
|
||||
*swapchain = new_swapchain;
|
||||
@ -415,7 +415,7 @@ fn main() {
|
||||
*recreate_swapchain = true;
|
||||
return;
|
||||
}
|
||||
Err(e) => panic!("Failed to acquire next image: {:?}", e),
|
||||
Err(e) => panic!("Failed to acquire next image: {e:?}"),
|
||||
};
|
||||
|
||||
if suboptimal {
|
||||
@ -470,7 +470,7 @@ fn main() {
|
||||
*previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to flush future: {:?}", e);
|
||||
println!("Failed to flush future: {e:?}");
|
||||
*previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ fn compute_then_render(
|
||||
// Start frame
|
||||
let before_pipeline_future = match window_renderer.acquire() {
|
||||
Err(e) => {
|
||||
println!("{}", e);
|
||||
println!("{e}");
|
||||
return;
|
||||
}
|
||||
Ok(future) => future,
|
||||
|
@ -24,7 +24,7 @@ use vulkano::{
|
||||
pipeline::{
|
||||
graphics::{
|
||||
input_assembly::InputAssemblyState,
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline, Pipeline, PipelineBindPoint,
|
||||
@ -106,7 +106,7 @@ impl PixelsDrawPipeline {
|
||||
let vs = vs::load(gfx_queue.device().clone()).expect("failed to create shader module");
|
||||
let fs = fs::load(gfx_queue.device().clone()).expect("failed to create shader module");
|
||||
GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<TexturedVertex>())
|
||||
.vertex_input_state(TexturedVertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.input_assembly_state(InputAssemblyState::new())
|
||||
.fragment_shader(fs.entry_point("main").unwrap(), ())
|
||||
|
@ -35,7 +35,7 @@ use vulkano::{
|
||||
pipeline::{
|
||||
graphics::{
|
||||
input_assembly::InputAssemblyState,
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline,
|
||||
@ -254,7 +254,7 @@ fn main() {
|
||||
.unwrap();
|
||||
|
||||
let pipeline = GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<Vertex>())
|
||||
.vertex_input_state(Vertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.input_assembly_state(InputAssemblyState::new())
|
||||
.viewport_state(ViewportState::viewport_fixed_scissor_irrelevant([
|
||||
|
@ -31,7 +31,7 @@ use vulkano::{
|
||||
graphics::{
|
||||
depth_stencil::DepthStencilState,
|
||||
input_assembly::InputAssemblyState,
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline,
|
||||
@ -302,7 +302,7 @@ fn main() {
|
||||
.unwrap();
|
||||
|
||||
let pipeline = GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<Vertex>())
|
||||
.vertex_input_state(Vertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.input_assembly_state(InputAssemblyState::new())
|
||||
.viewport_state(ViewportState::viewport_dynamic_scissor_irrelevant())
|
||||
@ -363,7 +363,7 @@ fn main() {
|
||||
}) {
|
||||
Ok(r) => r,
|
||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
||||
Err(e) => panic!("Failed to recreate swapchain: {:?}", e),
|
||||
Err(e) => panic!("Failed to recreate swapchain: {e:?}"),
|
||||
};
|
||||
|
||||
swapchain = new_swapchain;
|
||||
@ -383,7 +383,7 @@ fn main() {
|
||||
recreate_swapchain = true;
|
||||
return;
|
||||
}
|
||||
Err(e) => panic!("Failed to acquire next image: {:?}", e),
|
||||
Err(e) => panic!("Failed to acquire next image: {e:?}"),
|
||||
};
|
||||
|
||||
if suboptimal {
|
||||
@ -475,7 +475,7 @@ fn main() {
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to flush future: {:?}", e);
|
||||
println!("Failed to flush future: {e:?}");
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ use vulkano::{
|
||||
graphics::{
|
||||
color_blend::ColorBlendState,
|
||||
input_assembly::{InputAssemblyState, PrimitiveTopology},
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline, Pipeline, PipelineBindPoint,
|
||||
@ -252,7 +252,7 @@ fn main() {
|
||||
|
||||
let subpass = Subpass::from(render_pass.clone(), 0).unwrap();
|
||||
let pipeline = GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<Vertex>())
|
||||
.vertex_input_state(Vertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.input_assembly_state(InputAssemblyState::new().topology(PrimitiveTopology::TriangleStrip))
|
||||
.viewport_state(ViewportState::viewport_dynamic_scissor_irrelevant())
|
||||
@ -313,7 +313,7 @@ fn main() {
|
||||
}) {
|
||||
Ok(r) => r,
|
||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
||||
Err(e) => panic!("Failed to recreate swapchain: {:?}", e),
|
||||
Err(e) => panic!("Failed to recreate swapchain: {e:?}"),
|
||||
};
|
||||
|
||||
swapchain = new_swapchain;
|
||||
@ -329,7 +329,7 @@ fn main() {
|
||||
recreate_swapchain = true;
|
||||
return;
|
||||
}
|
||||
Err(e) => panic!("Failed to acquire next image: {:?}", e),
|
||||
Err(e) => panic!("Failed to acquire next image: {e:?}"),
|
||||
};
|
||||
|
||||
if suboptimal {
|
||||
@ -389,7 +389,7 @@ fn main() {
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to flush future: {:?}", e);
|
||||
println!("Failed to flush future: {e:?}");
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ use vulkano::{
|
||||
graphics::{
|
||||
input_assembly::InputAssemblyState,
|
||||
rasterization::{CullMode, FrontFace, RasterizationState},
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline,
|
||||
@ -195,7 +195,7 @@ fn main() {
|
||||
};
|
||||
|
||||
let graphics_pipeline = GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<Vertex>())
|
||||
.vertex_input_state(Vertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.input_assembly_state(InputAssemblyState::new())
|
||||
.viewport_state(ViewportState::viewport_dynamic_scissor_irrelevant())
|
||||
@ -288,7 +288,7 @@ fn main() {
|
||||
}) {
|
||||
Ok(r) => r,
|
||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
||||
Err(e) => panic!("Failed to recreate swapchain: {:?}", e),
|
||||
Err(e) => panic!("Failed to recreate swapchain: {e:?}"),
|
||||
};
|
||||
|
||||
swapchain = new_swapchain;
|
||||
@ -304,7 +304,7 @@ fn main() {
|
||||
recreate_swapchain = true;
|
||||
return;
|
||||
}
|
||||
Err(e) => panic!("Failed to acquire next image: {:?}", e),
|
||||
Err(e) => panic!("Failed to acquire next image: {e:?}"),
|
||||
};
|
||||
|
||||
if suboptimal {
|
||||
@ -358,7 +358,7 @@ fn main() {
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to flush future: {:?}", e);
|
||||
println!("Failed to flush future: {e:?}");
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ use vulkano::{
|
||||
pipeline::{
|
||||
graphics::{
|
||||
color_blend::ColorBlendState,
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
layout::PipelineLayoutCreateInfo,
|
||||
@ -384,7 +384,7 @@ fn main() {
|
||||
|
||||
let subpass = Subpass::from(render_pass.clone(), 0).unwrap();
|
||||
let pipeline = GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<Vertex>())
|
||||
.vertex_input_state(Vertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.viewport_state(ViewportState::viewport_dynamic_scissor_irrelevant())
|
||||
.fragment_shader(fs.entry_point("main").unwrap(), ())
|
||||
@ -455,7 +455,7 @@ fn main() {
|
||||
}) {
|
||||
Ok(r) => r,
|
||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
||||
Err(e) => panic!("Failed to recreate swapchain: {:?}", e),
|
||||
Err(e) => panic!("Failed to recreate swapchain: {e:?}"),
|
||||
};
|
||||
|
||||
swapchain = new_swapchain;
|
||||
@ -471,7 +471,7 @@ fn main() {
|
||||
recreate_swapchain = true;
|
||||
return;
|
||||
}
|
||||
Err(e) => panic!("Failed to acquire next image: {:?}", e),
|
||||
Err(e) => panic!("Failed to acquire next image: {e:?}"),
|
||||
};
|
||||
|
||||
if suboptimal {
|
||||
@ -531,7 +531,7 @@ fn main() {
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to flush future: {:?}", e);
|
||||
println!("Failed to flush future: {e:?}");
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ fn main() {
|
||||
|
||||
let serialized = to_string_pretty(&bar, PrettyConfig::default()).unwrap();
|
||||
|
||||
println!("Serialized Bar: {}", serialized);
|
||||
println!("Serialized Bar: {serialized}");
|
||||
|
||||
let deserialized = from_str::<Bar>(&serialized).unwrap();
|
||||
|
||||
|
@ -34,7 +34,7 @@ use vulkano::{
|
||||
pipeline::{
|
||||
graphics::{
|
||||
input_assembly::{InputAssemblyState, PrimitiveTopology},
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline, PipelineBindPoint,
|
||||
@ -415,7 +415,7 @@ fn main() {
|
||||
|
||||
// Create a basic graphics pipeline for rendering particles.
|
||||
let graphics_pipeline = GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<Vertex>())
|
||||
.vertex_input_state(Vertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.input_assembly_state(InputAssemblyState::new().topology(PrimitiveTopology::PointList)) // Vertices will be rendered as a list of points.
|
||||
.viewport_state(ViewportState::viewport_fixed_scissor_irrelevant([viewport]))
|
||||
@ -464,7 +464,7 @@ fn main() {
|
||||
None, /*timeout*/
|
||||
) {
|
||||
Ok(tuple) => tuple,
|
||||
Err(e) => panic!("Failed to acquire next image: {:?}", e),
|
||||
Err(e) => panic!("Failed to acquire next image: {e:?}"),
|
||||
};
|
||||
|
||||
// Since we disallow resizing, assert the swapchain and surface are optimally configured.
|
||||
@ -542,7 +542,7 @@ fn main() {
|
||||
Ok(future) => Some(Arc::new(future)),
|
||||
|
||||
// Unknown failure.
|
||||
Err(e) => panic!("Failed to flush future: {:?}", e),
|
||||
Err(e) => panic!("Failed to flush future: {e:?}"),
|
||||
};
|
||||
previous_fence_index = image_index;
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ use vulkano::{
|
||||
graphics::{
|
||||
depth_stencil::DepthStencilState,
|
||||
input_assembly::InputAssemblyState,
|
||||
vertex_input::BuffersDefinition,
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline, Pipeline, PipelineBindPoint,
|
||||
@ -258,7 +258,7 @@ fn main() {
|
||||
}) {
|
||||
Ok(r) => r,
|
||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
||||
Err(e) => panic!("Failed to recreate swapchain: {:?}", e),
|
||||
Err(e) => panic!("Failed to recreate swapchain: {e:?}"),
|
||||
};
|
||||
|
||||
swapchain = new_swapchain;
|
||||
@ -321,7 +321,7 @@ fn main() {
|
||||
recreate_swapchain = true;
|
||||
return;
|
||||
}
|
||||
Err(e) => panic!("Failed to acquire next image: {:?}", e),
|
||||
Err(e) => panic!("Failed to acquire next image: {e:?}"),
|
||||
};
|
||||
|
||||
if suboptimal {
|
||||
@ -384,7 +384,7 @@ fn main() {
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to flush future: {:?}", e);
|
||||
println!("Failed to flush future: {e:?}");
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
}
|
||||
@ -429,11 +429,7 @@ fn window_size_dependent_setup(
|
||||
// This allows the driver to optimize things, at the cost of slower window resizes.
|
||||
// https://computergraphics.stackexchange.com/questions/5742/vulkan-best-way-of-updating-pipeline-viewport
|
||||
let pipeline = GraphicsPipeline::start()
|
||||
.vertex_input_state(
|
||||
BuffersDefinition::new()
|
||||
.vertex::<Position>()
|
||||
.vertex::<Normal>(),
|
||||
)
|
||||
.vertex_input_state([Position::per_vertex(), Normal::per_vertex()])
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.input_assembly_state(InputAssemblyState::new())
|
||||
.viewport_state(ViewportState::viewport_fixed_scissor_irrelevant([
|
||||
|
@ -38,7 +38,7 @@ use vulkano::{
|
||||
input_assembly::{InputAssemblyState, PrimitiveTopology},
|
||||
rasterization::{PolygonMode, RasterizationState},
|
||||
tessellation::TessellationState,
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline,
|
||||
@ -329,7 +329,7 @@ fn main() {
|
||||
.unwrap();
|
||||
|
||||
let pipeline = GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<Vertex>())
|
||||
.vertex_input_state(Vertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
// Actually use the tessellation shaders.
|
||||
.tessellation_shaders(
|
||||
@ -394,7 +394,7 @@ fn main() {
|
||||
}) {
|
||||
Ok(r) => r,
|
||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
||||
Err(e) => panic!("Failed to recreate swapchain: {:?}", e),
|
||||
Err(e) => panic!("Failed to recreate swapchain: {e:?}"),
|
||||
};
|
||||
|
||||
swapchain = new_swapchain;
|
||||
@ -410,7 +410,7 @@ fn main() {
|
||||
recreate_swapchain = true;
|
||||
return;
|
||||
}
|
||||
Err(e) => panic!("Failed to acquire next image: {:?}", e),
|
||||
Err(e) => panic!("Failed to acquire next image: {e:?}"),
|
||||
};
|
||||
|
||||
if suboptimal {
|
||||
@ -464,7 +464,7 @@ fn main() {
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to flush future: {:?}", e);
|
||||
println!("Failed to flush future: {e:?}");
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ use vulkano::{
|
||||
graphics::{
|
||||
color_blend::ColorBlendState,
|
||||
input_assembly::{InputAssemblyState, PrimitiveTopology},
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline, Pipeline, PipelineBindPoint,
|
||||
@ -258,7 +258,7 @@ fn main() {
|
||||
|
||||
let subpass = Subpass::from(render_pass.clone(), 0).unwrap();
|
||||
let pipeline = GraphicsPipeline::start()
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<Vertex>())
|
||||
.vertex_input_state(Vertex::per_vertex())
|
||||
.vertex_shader(vs.entry_point("main").unwrap(), ())
|
||||
.input_assembly_state(InputAssemblyState::new().topology(PrimitiveTopology::TriangleStrip))
|
||||
.viewport_state(ViewportState::viewport_dynamic_scissor_irrelevant())
|
||||
@ -322,7 +322,7 @@ fn main() {
|
||||
}) {
|
||||
Ok(r) => r,
|
||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
||||
Err(e) => panic!("Failed to recreate swapchain: {:?}", e),
|
||||
Err(e) => panic!("Failed to recreate swapchain: {e:?}"),
|
||||
};
|
||||
|
||||
swapchain = new_swapchain;
|
||||
@ -338,7 +338,7 @@ fn main() {
|
||||
recreate_swapchain = true;
|
||||
return;
|
||||
}
|
||||
Err(e) => panic!("Failed to acquire next image: {:?}", e),
|
||||
Err(e) => panic!("Failed to acquire next image: {e:?}"),
|
||||
};
|
||||
|
||||
if suboptimal {
|
||||
@ -398,7 +398,7 @@ fn main() {
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to flush future: {:?}", e);
|
||||
println!("Failed to flush future: {e:?}");
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ use vulkano::{
|
||||
graphics::{
|
||||
input_assembly::InputAssemblyState,
|
||||
render_pass::PipelineRenderingCreateInfo,
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline,
|
||||
@ -375,7 +375,7 @@ fn main() {
|
||||
..Default::default()
|
||||
})
|
||||
// We need to indicate the layout of the vertices.
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<Vertex>())
|
||||
.vertex_input_state(Vertex::per_vertex())
|
||||
// The content of the vertex buffer describes a list of triangles.
|
||||
.input_assembly_state(InputAssemblyState::new())
|
||||
// A Vulkan shader can in theory contain multiple entry points, so we have to specify
|
||||
@ -467,7 +467,7 @@ fn main() {
|
||||
// This error tends to happen when the user is manually resizing the window.
|
||||
// Simply restarting the loop is the easiest way to fix this issue.
|
||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
||||
Err(e) => panic!("Failed to recreate swapchain: {:?}", e),
|
||||
Err(e) => panic!("Failed to recreate swapchain: {e:?}"),
|
||||
};
|
||||
|
||||
swapchain = new_swapchain;
|
||||
@ -492,7 +492,7 @@ fn main() {
|
||||
recreate_swapchain = true;
|
||||
return;
|
||||
}
|
||||
Err(e) => panic!("Failed to acquire next image: {:?}", e),
|
||||
Err(e) => panic!("Failed to acquire next image: {e:?}"),
|
||||
};
|
||||
|
||||
// acquire_next_image can be successful, but suboptimal. This means that the swapchain image
|
||||
@ -590,7 +590,7 @@ fn main() {
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to flush future: {:?}", e);
|
||||
println!("Failed to flush future: {e:?}");
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ use vulkano::{
|
||||
pipeline::{
|
||||
graphics::{
|
||||
input_assembly::InputAssemblyState,
|
||||
vertex_input::{BuffersDefinition, Vertex},
|
||||
vertex_input::Vertex,
|
||||
viewport::{Viewport, ViewportState},
|
||||
},
|
||||
GraphicsPipeline,
|
||||
@ -383,7 +383,7 @@ fn main() {
|
||||
// in. The pipeline will only be usable from this particular subpass.
|
||||
.render_pass(Subpass::from(render_pass.clone(), 0).unwrap())
|
||||
// We need to indicate the layout of the vertices.
|
||||
.vertex_input_state(BuffersDefinition::new().vertex::<Vertex>())
|
||||
.vertex_input_state(Vertex::per_vertex())
|
||||
// The content of the vertex buffer describes a list of triangles.
|
||||
.input_assembly_state(InputAssemblyState::new())
|
||||
// A Vulkan shader can in theory contain multiple entry points, so we have to specify
|
||||
@ -482,7 +482,7 @@ fn main() {
|
||||
// This error tends to happen when the user is manually resizing the window.
|
||||
// Simply restarting the loop is the easiest way to fix this issue.
|
||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
||||
Err(e) => panic!("Failed to recreate swapchain: {:?}", e),
|
||||
Err(e) => panic!("Failed to recreate swapchain: {e:?}"),
|
||||
};
|
||||
|
||||
swapchain = new_swapchain;
|
||||
@ -510,7 +510,7 @@ fn main() {
|
||||
recreate_swapchain = true;
|
||||
return;
|
||||
}
|
||||
Err(e) => panic!("Failed to acquire next image: {:?}", e),
|
||||
Err(e) => panic!("Failed to acquire next image: {e:?}"),
|
||||
};
|
||||
|
||||
// acquire_next_image can be successful, but suboptimal. This means that the swapchain image
|
||||
@ -601,7 +601,7 @@ fn main() {
|
||||
previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
Err(e) => {
|
||||
panic!("Failed to flush future: {:?}", e);
|
||||
panic!("Failed to flush future: {e:?}");
|
||||
// previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||
}
|
||||
}
|
||||
|
@ -41,14 +41,16 @@ pub fn derive_vertex(ast: syn::DeriveInput) -> Result<TokenStream> {
|
||||
FoundCrate::Name(name) => Ident::new(&name, Span::call_site()),
|
||||
};
|
||||
|
||||
let mut member_cases = quote! {
|
||||
let mut members = quote! {
|
||||
let mut offset = 0;
|
||||
let mut members = HashMap::default();
|
||||
};
|
||||
|
||||
for field in fields.iter() {
|
||||
let field_name = field.ident.to_owned().unwrap();
|
||||
let field_name_lit = LitStr::new(&field_name.to_string(), Span::call_site());
|
||||
let field_ty = &field.ty;
|
||||
let mut names = vec![LitStr::new(&field_name.to_string(), Span::call_site())];
|
||||
let mut names = vec![field_name_lit.clone()];
|
||||
let mut format = quote! {};
|
||||
for attr in &field.attrs {
|
||||
let attr_ident = if let Some(ident) = attr.path.get_ident() {
|
||||
@ -73,42 +75,61 @@ pub fn derive_vertex(ast: syn::DeriveInput) -> Result<TokenStream> {
|
||||
));
|
||||
}
|
||||
for name in &names {
|
||||
member_cases = quote! {
|
||||
#member_cases
|
||||
members = quote! {
|
||||
#members
|
||||
|
||||
let field_size = std::mem::size_of::<#field_ty>() as u32;
|
||||
if name == #name {
|
||||
{
|
||||
#format
|
||||
let format_size = format.block_size().expect("no block size for format") as u32;
|
||||
let num_elements = field_size / format_size;
|
||||
let remainder = field_size % format_size;
|
||||
assert!(remainder == 0, "struct field `{}` size does not fit multiple of format size", name);
|
||||
return Some(VertexMemberInfo {
|
||||
offset,
|
||||
format,
|
||||
num_elements,
|
||||
});
|
||||
assert!(remainder == 0, "struct field `{}` size does not fit multiple of format size", #field_name_lit);
|
||||
members.insert(
|
||||
#name.to_string(),
|
||||
VertexMemberInfo {
|
||||
offset,
|
||||
format,
|
||||
num_elements,
|
||||
},
|
||||
);
|
||||
}
|
||||
offset += field_size as usize;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Ok(TokenStream::from(quote! {
|
||||
#[allow(unsafe_code)]
|
||||
unsafe impl #crate_ident::pipeline::graphics::vertex_input::Vertex for #struct_name {
|
||||
#[inline(always)]
|
||||
fn member(name: &str) -> Option<#crate_ident::pipeline::graphics::vertex_input::VertexMemberInfo> {
|
||||
#[allow(unused_imports)]
|
||||
use #crate_ident::format::Format;
|
||||
use #crate_ident::pipeline::graphics::vertex_input::VertexMemberInfo;
|
||||
use #crate_ident::pipeline::graphics::vertex_input::VertexMember;
|
||||
let function_body = quote! {
|
||||
#[allow(unused_imports)]
|
||||
use std::collections::HashMap;
|
||||
use #crate_ident::format::Format;
|
||||
use #crate_ident::pipeline::graphics::vertex_input::{VertexInputRate, VertexMemberInfo};
|
||||
|
||||
#member_cases
|
||||
#members
|
||||
|
||||
None
|
||||
}
|
||||
#crate_ident::pipeline::graphics::vertex_input::VertexBufferDescription {
|
||||
members,
|
||||
stride: std::mem::size_of::<#struct_name>() as u32,
|
||||
input_rate: VertexInputRate::Vertex,
|
||||
}
|
||||
};
|
||||
|
||||
Ok(TokenStream::from(quote! {
|
||||
#[allow(unsafe_code)]
|
||||
unsafe impl #crate_ident::pipeline::graphics::vertex_input::Vertex for #struct_name {
|
||||
#[inline(always)]
|
||||
fn per_vertex() -> #crate_ident::pipeline::graphics::vertex_input::VertexBufferDescription {
|
||||
#function_body
|
||||
}
|
||||
#[inline(always)]
|
||||
fn per_instance() -> #crate_ident::pipeline::graphics::vertex_input::VertexBufferDescription {
|
||||
#function_body.per_instance()
|
||||
}
|
||||
#[inline(always)]
|
||||
fn per_instance_with_divisor(divisor: u32) -> #crate_ident::pipeline::graphics::vertex_input::VertexBufferDescription {
|
||||
#function_body.per_instance_with_divisor(divisor)
|
||||
}
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -71,14 +71,19 @@
|
||||
//! use vulkano::command_buffer::PrimaryCommandBufferAbstract;
|
||||
//! use vulkano::command_buffer::SubpassContents;
|
||||
//!
|
||||
//! # use vulkano::pipeline::graphics::vertex_input::Vertex;
|
||||
//! # use bytemuck::{Pod, Zeroable};
|
||||
//!
|
||||
//! # #[repr(C)]
|
||||
//! # #[derive(Clone, Copy, Debug, Default, bytemuck::Zeroable, bytemuck::Pod)]
|
||||
//! # struct Vertex { position: [f32; 3] };
|
||||
//! # vulkano::impl_vertex!(Vertex, position);
|
||||
//! # #[derive(Clone, Copy, Debug, Default, Zeroable, Pod, Vertex)]
|
||||
//! # struct PosVertex {
|
||||
//! # #[format(R32G32B32_SFLOAT)]
|
||||
//! # position: [f32; 3]
|
||||
//! # };
|
||||
//! # use vulkano::buffer::TypedBufferAccess;
|
||||
//! # let device: std::sync::Arc<vulkano::device::Device> = return;
|
||||
//! # let queue: std::sync::Arc<vulkano::device::Queue> = return;
|
||||
//! # let vertex_buffer: std::sync::Arc<vulkano::buffer::CpuAccessibleBuffer<[Vertex]>> = return;
|
||||
//! # let vertex_buffer: std::sync::Arc<vulkano::buffer::CpuAccessibleBuffer<[PosVertex]>> = return;
|
||||
//! # let render_pass_begin_info: vulkano::command_buffer::RenderPassBeginInfo = return;
|
||||
//! # let graphics_pipeline: std::sync::Arc<vulkano::pipeline::graphics::GraphicsPipeline> = return;
|
||||
//! # let command_buffer_allocator: vulkano::command_buffer::allocator::StandardCommandBufferAllocator = return;
|
||||
|
@ -25,8 +25,8 @@ use super::{
|
||||
render_pass::{PipelineRenderPassType, PipelineRenderingCreateInfo},
|
||||
tessellation::TessellationState,
|
||||
vertex_input::{
|
||||
BuffersDefinition, Vertex, VertexDefinition, VertexInputAttributeDescription,
|
||||
VertexInputBindingDescription, VertexInputState,
|
||||
VertexDefinition, VertexInputAttributeDescription, VertexInputBindingDescription,
|
||||
VertexInputState,
|
||||
},
|
||||
viewport::{Scissor, Viewport, ViewportState},
|
||||
GraphicsPipeline, GraphicsPipelineCreationError,
|
||||
@ -3997,29 +3997,6 @@ impl<'vs, 'tcs, 'tes, 'gs, 'fs, Vdef, Vss, Tcss, Tess, Gss, Fss>
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the vertex input to a single vertex buffer.
|
||||
///
|
||||
/// You will most likely need to explicitly specify the template parameter to the type of a
|
||||
/// vertex.
|
||||
#[deprecated(since = "0.27.0", note = "Use `vertex_input_state` instead")]
|
||||
pub fn vertex_input_single_buffer<V: Vertex>(
|
||||
self,
|
||||
) -> GraphicsPipelineBuilder<
|
||||
'vs,
|
||||
'tcs,
|
||||
'tes,
|
||||
'gs,
|
||||
'fs,
|
||||
BuffersDefinition,
|
||||
Vss,
|
||||
Tcss,
|
||||
Tess,
|
||||
Gss,
|
||||
Fss,
|
||||
> {
|
||||
self.vertex_input_state(BuffersDefinition::new().vertex::<V>())
|
||||
}
|
||||
|
||||
/// Sets whether primitive restart is enabled.
|
||||
#[deprecated(since = "0.27.0", note = "Use `input_assembly_state` instead")]
|
||||
#[inline]
|
||||
|
@ -7,50 +7,23 @@
|
||||
// notice may not be copied, modified, or distributed except
|
||||
// according to those terms.
|
||||
|
||||
use super::VertexMemberInfo;
|
||||
use super::VertexBufferDescription;
|
||||
use crate::{
|
||||
pipeline::graphics::vertex_input::{
|
||||
IncompatibleVertexDefinitionError, Vertex, VertexDefinition,
|
||||
VertexInputAttributeDescription, VertexInputBindingDescription, VertexInputRate,
|
||||
VertexInputState,
|
||||
IncompatibleVertexDefinitionError, Vertex, VertexDefinition, VertexInputState,
|
||||
},
|
||||
shader::ShaderInterface,
|
||||
DeviceSize,
|
||||
};
|
||||
use std::{
|
||||
fmt::{Debug, Error as FmtError, Formatter},
|
||||
mem,
|
||||
};
|
||||
|
||||
/// A vertex definition for any number of vertex and instance buffers.
|
||||
#[deprecated(
|
||||
since = "0.33.0",
|
||||
note = "Use `VertexBufferDescription` directly instead as returned by `Vertex::per_vertex` or `Vertex::per_instance`"
|
||||
)]
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct BuffersDefinition(Vec<VertexBuffer>);
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct VertexBuffer {
|
||||
info_fn: fn(&str) -> Option<VertexMemberInfo>,
|
||||
stride: u32,
|
||||
input_rate: VertexInputRate,
|
||||
}
|
||||
|
||||
impl Debug for VertexBuffer {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||
f.debug_struct("VertexBuffer")
|
||||
.field("stride", &self.stride)
|
||||
.field("input_rate", &self.input_rate)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VertexBuffer> for VertexInputBindingDescription {
|
||||
fn from(val: VertexBuffer) -> Self {
|
||||
Self {
|
||||
stride: val.stride,
|
||||
input_rate: val.input_rate,
|
||||
}
|
||||
}
|
||||
}
|
||||
pub struct BuffersDefinition(Vec<VertexBufferDescription>);
|
||||
|
||||
#[allow(deprecated)]
|
||||
impl BuffersDefinition {
|
||||
/// Constructs a new definition.
|
||||
#[inline]
|
||||
@ -60,23 +33,13 @@ impl BuffersDefinition {
|
||||
|
||||
/// Adds a new vertex buffer containing elements of type `V` to the definition.
|
||||
pub fn vertex<V: Vertex>(mut self) -> Self {
|
||||
self.0.push(VertexBuffer {
|
||||
info_fn: V::member,
|
||||
stride: mem::size_of::<V>() as u32,
|
||||
input_rate: VertexInputRate::Vertex,
|
||||
});
|
||||
|
||||
self.0.push(V::per_vertex());
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a new instance buffer containing elements of type `V` to the definition.
|
||||
pub fn instance<V: Vertex>(mut self) -> Self {
|
||||
self.0.push(VertexBuffer {
|
||||
info_fn: V::member,
|
||||
stride: mem::size_of::<V>() as u32,
|
||||
input_rate: VertexInputRate::Instance { divisor: 1 },
|
||||
});
|
||||
|
||||
self.0.push(V::per_instance());
|
||||
self
|
||||
}
|
||||
|
||||
@ -92,83 +55,18 @@ impl BuffersDefinition {
|
||||
/// [`vertex_attribute_instance_rate_divisor`]: crate::device::Features::vertex_attribute_instance_rate_divisor
|
||||
/// [`vertex_attribute_instance_rate_zero_divisor`]: crate::device::Features::vertex_attribute_instance_rate_zero_divisor
|
||||
pub fn instance_with_divisor<V: Vertex>(mut self, divisor: u32) -> Self {
|
||||
self.0.push(VertexBuffer {
|
||||
info_fn: V::member,
|
||||
stride: mem::size_of::<V>() as u32,
|
||||
input_rate: VertexInputRate::Instance { divisor },
|
||||
});
|
||||
|
||||
self.0.push(V::per_instance_with_divisor(divisor));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
unsafe impl VertexDefinition for BuffersDefinition {
|
||||
#[inline]
|
||||
fn definition(
|
||||
&self,
|
||||
interface: &ShaderInterface,
|
||||
) -> Result<VertexInputState, IncompatibleVertexDefinitionError> {
|
||||
let bindings = self
|
||||
.0
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(binding, &buffer)| (binding as u32, buffer.into()));
|
||||
let mut attributes: Vec<(u32, VertexInputAttributeDescription)> = Vec::new();
|
||||
|
||||
for element in interface.elements() {
|
||||
let name = element.name.as_ref().unwrap();
|
||||
|
||||
let (infos, binding) = self
|
||||
.0
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(binding, buffer)| {
|
||||
(buffer.info_fn)(name).map(|infos| (infos, binding as u32))
|
||||
})
|
||||
.ok_or_else(||
|
||||
// TODO: move this check to GraphicsPipelineBuilder
|
||||
IncompatibleVertexDefinitionError::MissingAttribute {
|
||||
attribute: name.clone().into_owned(),
|
||||
})?;
|
||||
|
||||
// TODO: ShaderInterfaceEntryType does not properly support 64bit.
|
||||
// Once it does the below logic around num_elements and num_locations
|
||||
// might have to be updated.
|
||||
if infos.num_components() != element.ty.num_components
|
||||
|| infos.num_elements != element.ty.num_locations()
|
||||
{
|
||||
return Err(IncompatibleVertexDefinitionError::FormatMismatch {
|
||||
attribute: name.clone().into_owned(),
|
||||
shader: element.ty,
|
||||
definition: infos,
|
||||
});
|
||||
}
|
||||
|
||||
let mut offset = infos.offset as DeviceSize;
|
||||
let block_size = infos.format.block_size().unwrap();
|
||||
// Double precision formats can exceed a single location.
|
||||
// R64B64G64A64_SFLOAT requires two locations, so we need to adapt how we bind
|
||||
let location_range = if block_size > 16 {
|
||||
(element.location..element.location + 2 * element.ty.num_locations()).step_by(2)
|
||||
} else {
|
||||
(element.location..element.location + element.ty.num_locations()).step_by(1)
|
||||
};
|
||||
|
||||
for location in location_range {
|
||||
attributes.push((
|
||||
location,
|
||||
VertexInputAttributeDescription {
|
||||
binding,
|
||||
format: infos.format,
|
||||
offset: offset as u32,
|
||||
},
|
||||
));
|
||||
offset += block_size;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(VertexInputState::new()
|
||||
.bindings(bindings)
|
||||
.attributes(attributes))
|
||||
self.0.definition(interface)
|
||||
}
|
||||
}
|
||||
|
@ -50,9 +50,13 @@
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use super::{
|
||||
VertexBufferDescription, VertexInputAttributeDescription, VertexInputBindingDescription,
|
||||
};
|
||||
use crate::{
|
||||
pipeline::graphics::vertex_input::{VertexInputState, VertexMemberInfo},
|
||||
shader::{ShaderInterface, ShaderInterfaceEntryType},
|
||||
DeviceSize,
|
||||
};
|
||||
use std::{
|
||||
error::Error,
|
||||
@ -113,3 +117,110 @@ impl Display for IncompatibleVertexDefinitionError {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl VertexDefinition for &[VertexBufferDescription] {
|
||||
#[inline]
|
||||
fn definition(
|
||||
&self,
|
||||
interface: &ShaderInterface,
|
||||
) -> Result<VertexInputState, IncompatibleVertexDefinitionError> {
|
||||
let bindings = self.iter().enumerate().map(|(binding, buffer)| {
|
||||
(
|
||||
binding as u32,
|
||||
VertexInputBindingDescription {
|
||||
stride: buffer.stride,
|
||||
input_rate: buffer.input_rate,
|
||||
},
|
||||
)
|
||||
});
|
||||
let mut attributes: Vec<(u32, VertexInputAttributeDescription)> = Vec::new();
|
||||
|
||||
for element in interface.elements() {
|
||||
let name = element.name.as_ref().unwrap().clone().into_owned();
|
||||
|
||||
let (infos, binding) = self
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(binding, buffer)| {
|
||||
buffer
|
||||
.members
|
||||
.get(&name)
|
||||
.map(|infos| (infos.clone(), binding as u32))
|
||||
})
|
||||
.ok_or_else(||
|
||||
// TODO: move this check to GraphicsPipelineBuilder
|
||||
IncompatibleVertexDefinitionError::MissingAttribute {
|
||||
attribute: name.clone(),
|
||||
})?;
|
||||
|
||||
// TODO: ShaderInterfaceEntryType does not properly support 64bit.
|
||||
// Once it does the below logic around num_elements and num_locations
|
||||
// might have to be updated.
|
||||
if infos.num_components() != element.ty.num_components
|
||||
|| infos.num_elements != element.ty.num_locations()
|
||||
{
|
||||
return Err(IncompatibleVertexDefinitionError::FormatMismatch {
|
||||
attribute: name,
|
||||
shader: element.ty,
|
||||
definition: infos,
|
||||
});
|
||||
}
|
||||
|
||||
let mut offset = infos.offset as DeviceSize;
|
||||
let block_size = infos.format.block_size().unwrap();
|
||||
// Double precision formats can exceed a single location.
|
||||
// R64B64G64A64_SFLOAT requires two locations, so we need to adapt how we bind
|
||||
let location_range = if block_size > 16 {
|
||||
(element.location..element.location + 2 * element.ty.num_locations()).step_by(2)
|
||||
} else {
|
||||
(element.location..element.location + element.ty.num_locations()).step_by(1)
|
||||
};
|
||||
|
||||
for location in location_range {
|
||||
attributes.push((
|
||||
location,
|
||||
VertexInputAttributeDescription {
|
||||
binding,
|
||||
format: infos.format,
|
||||
offset: offset as u32,
|
||||
},
|
||||
));
|
||||
offset += block_size;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(VertexInputState::new()
|
||||
.bindings(bindings)
|
||||
.attributes(attributes))
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<const N: usize> VertexDefinition for [VertexBufferDescription; N] {
|
||||
#[inline]
|
||||
fn definition(
|
||||
&self,
|
||||
interface: &ShaderInterface,
|
||||
) -> Result<VertexInputState, IncompatibleVertexDefinitionError> {
|
||||
self.as_slice().definition(interface)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl VertexDefinition for Vec<VertexBufferDescription> {
|
||||
#[inline]
|
||||
fn definition(
|
||||
&self,
|
||||
interface: &ShaderInterface,
|
||||
) -> Result<VertexInputState, IncompatibleVertexDefinitionError> {
|
||||
self.as_slice().definition(interface)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl VertexDefinition for VertexBufferDescription {
|
||||
#[inline]
|
||||
fn definition(
|
||||
&self,
|
||||
interface: &ShaderInterface,
|
||||
) -> Result<VertexInputState, IncompatibleVertexDefinitionError> {
|
||||
std::slice::from_ref(self).definition(interface)
|
||||
}
|
||||
}
|
||||
|
@ -35,14 +35,16 @@ macro_rules! impl_vertex {
|
||||
unsafe impl $crate::pipeline::graphics::vertex_input::Vertex for $out {
|
||||
#[inline(always)]
|
||||
#[allow(deprecated)]
|
||||
fn member(name: &str) -> Option<$crate::pipeline::graphics::vertex_input::VertexMemberInfo> {
|
||||
fn per_vertex() -> $crate::pipeline::graphics::vertex_input::VertexBufferDescription {
|
||||
#[allow(unused_imports)]
|
||||
use std::collections::HashMap;
|
||||
use $crate::format::Format;
|
||||
use $crate::pipeline::graphics::vertex_input::VertexMemberInfo;
|
||||
use $crate::pipeline::graphics::vertex_input::VertexMember;
|
||||
use $crate::pipeline::graphics::vertex_input::{VertexInputRate, VertexMemberInfo};
|
||||
|
||||
let mut members = HashMap::default();
|
||||
$(
|
||||
if name == stringify!($member) {
|
||||
{
|
||||
let dummy = <$out>::default();
|
||||
#[inline] fn f<T: VertexMember>(_: &T) -> Format { T::format() }
|
||||
let format = f(&dummy.$member);
|
||||
@ -58,12 +60,12 @@ macro_rules! impl_vertex {
|
||||
let format_size = format.block_size().expect("no block size for format") as u32;
|
||||
let num_elements = field_size / format_size;
|
||||
let remainder = field_size % format_size;
|
||||
assert!(remainder == 0, "struct field `{}` size does not fit multiple of format size", name);
|
||||
assert!(remainder == 0, "struct field `{}` size does not fit multiple of format size", stringify!($member));
|
||||
|
||||
let dummy_ptr = (&dummy) as *const _;
|
||||
let member_ptr = (&dummy.$member) as *const _;
|
||||
|
||||
return Some(VertexMemberInfo {
|
||||
members.insert(stringify!($member).to_string(), VertexMemberInfo {
|
||||
offset: member_ptr as usize - dummy_ptr as usize,
|
||||
format,
|
||||
num_elements,
|
||||
@ -71,8 +73,23 @@ macro_rules! impl_vertex {
|
||||
}
|
||||
)*
|
||||
|
||||
None
|
||||
$crate::pipeline::graphics::vertex_input::VertexBufferDescription {
|
||||
members,
|
||||
stride: std::mem::size_of::<$out>() as u32,
|
||||
input_rate: VertexInputRate::Vertex,
|
||||
}
|
||||
}
|
||||
#[inline(always)]
|
||||
#[allow(deprecated)]
|
||||
fn per_instance() -> $crate::pipeline::graphics::vertex_input::VertexBufferDescription {
|
||||
<$out as $crate::pipeline::graphics::vertex_input::Vertex>::per_vertex().per_instance()
|
||||
}
|
||||
#[inline(always)]
|
||||
#[allow(deprecated)]
|
||||
fn per_instance_with_divisor(divisor: u32) -> $crate::pipeline::graphics::vertex_input::VertexBufferDescription {
|
||||
<$out as $crate::pipeline::graphics::vertex_input::Vertex>::per_vertex().per_instance_with_divisor(divisor)
|
||||
}
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -223,9 +240,10 @@ mod tests {
|
||||
}
|
||||
impl_vertex!(TestVertex, scalar, vector, matrix);
|
||||
|
||||
let matrix = TestVertex::member("matrix").unwrap();
|
||||
let vector = TestVertex::member("vector").unwrap();
|
||||
let scalar = TestVertex::member("scalar").unwrap();
|
||||
let info = TestVertex::per_vertex();
|
||||
let matrix = info.members.get("matrix").unwrap();
|
||||
let vector = info.members.get("vector").unwrap();
|
||||
let scalar = info.members.get("scalar").unwrap();
|
||||
assert_eq!(matrix.format, Format::R32G32B32A32_SFLOAT);
|
||||
assert_eq!(matrix.offset, 0);
|
||||
assert_eq!(matrix.num_elements, 4);
|
||||
|
@ -104,7 +104,7 @@ pub use self::{
|
||||
collection::VertexBuffersCollection,
|
||||
definition::{IncompatibleVertexDefinitionError, VertexDefinition},
|
||||
impl_vertex::VertexMember,
|
||||
vertex::{Vertex, VertexMemberInfo},
|
||||
vertex::{Vertex, VertexBufferDescription, VertexMemberInfo},
|
||||
};
|
||||
use crate::format::Format;
|
||||
use ahash::HashMap;
|
||||
|
@ -7,8 +7,10 @@
|
||||
// notice may not be copied, modified, or distributed except
|
||||
// according to those terms.
|
||||
|
||||
use super::VertexInputRate;
|
||||
use crate::format::Format;
|
||||
use bytemuck::Pod;
|
||||
use std::collections::HashMap;
|
||||
pub use vulkano_macros::Vertex;
|
||||
|
||||
/// Describes an individual `Vertex`. In other words a collection of attributes that can be read
|
||||
@ -37,14 +39,51 @@ pub use vulkano_macros::Vertex;
|
||||
/// }
|
||||
/// ```
|
||||
pub unsafe trait Vertex: Pod + Send + Sync + 'static {
|
||||
/// Returns the characteristics of a vertex member by its name.
|
||||
fn member(name: &str) -> Option<VertexMemberInfo>;
|
||||
/// Returns the information about this Vertex type.
|
||||
fn per_vertex() -> VertexBufferDescription;
|
||||
fn per_instance() -> VertexBufferDescription;
|
||||
fn per_instance_with_divisor(divisor: u32) -> VertexBufferDescription;
|
||||
}
|
||||
|
||||
unsafe impl Vertex for () {
|
||||
/// Describes the contents of a VertexBuffer.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct VertexBufferDescription {
|
||||
/// List of member names with their detailed information.
|
||||
pub members: HashMap<String, VertexMemberInfo>,
|
||||
/// Stride of the vertex type in a buffer.
|
||||
pub stride: u32,
|
||||
/// How the vertex buffer is unrolled in the shader.
|
||||
pub input_rate: VertexInputRate,
|
||||
}
|
||||
|
||||
impl VertexBufferDescription {
|
||||
#[inline]
|
||||
fn member(_: &str) -> Option<VertexMemberInfo> {
|
||||
None
|
||||
pub fn per_vertex(self) -> VertexBufferDescription {
|
||||
let VertexBufferDescription {
|
||||
members, stride, ..
|
||||
} = self;
|
||||
VertexBufferDescription {
|
||||
members,
|
||||
stride,
|
||||
input_rate: VertexInputRate::Vertex,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn per_instance(self) -> VertexBufferDescription {
|
||||
self.per_instance_with_divisor(1)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn per_instance_with_divisor(self, divisor: u32) -> VertexBufferDescription {
|
||||
let VertexBufferDescription {
|
||||
members, stride, ..
|
||||
} = self;
|
||||
VertexBufferDescription {
|
||||
members,
|
||||
stride,
|
||||
input_rate: VertexInputRate::Instance { divisor },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,8 +126,9 @@ mod tests {
|
||||
a: [f32; 16],
|
||||
}
|
||||
|
||||
let b = TestVertex::member("b").unwrap();
|
||||
let c = TestVertex::member("c").unwrap();
|
||||
let info = TestVertex::per_vertex();
|
||||
let b = info.members.get("b").unwrap();
|
||||
let c = info.members.get("c").unwrap();
|
||||
assert_eq!(b.format, Format::R32G32B32A32_SFLOAT);
|
||||
assert_eq!(c.format, Format::R32G32B32A32_SFLOAT);
|
||||
assert_eq!(b.num_elements, 4);
|
||||
@ -104,7 +144,8 @@ mod tests {
|
||||
unorm: u8,
|
||||
}
|
||||
|
||||
let unorm = TestVertex::member("unorm").unwrap();
|
||||
let info = TestVertex::per_instance();
|
||||
let unorm = info.members.get("unorm").unwrap();
|
||||
assert_eq!(unorm.format, Format::R8_UNORM);
|
||||
assert_eq!(unorm.num_elements, 1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user