Make dynamic state future-proof and more Vulkan-y (#2348)

* Make dynamic state future-proof and more Vulkan-y

* Additional fixes

* Extra docs

* Oops

* Derp!

* Review fixes
This commit is contained in:
Rua 2023-10-07 16:46:03 +02:00 committed by GitHub
parent 5a98b0ba91
commit 0fed9bbc7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 1858 additions and 2442 deletions

View File

@ -71,7 +71,7 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::ColorBlendState,
color_blend::{ColorBlendAttachmentState, ColorBlendState},
input_assembly::{InputAssemblyState, PrimitiveTopology},
multisample::MultisampleState,
rasterization::RasterizationState,
@ -80,7 +80,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
PipelineShaderStageCreateInfo,
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
@ -456,13 +456,18 @@ fn main() {
GraphicsPipelineCreateInfo {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(
InputAssemblyState::new().topology(PrimitiveTopology::TriangleStrip),
),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
input_assembly_state: Some(InputAssemblyState {
topology: PrimitiveTopology::TriangleStrip,
..Default::default()
}),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState::default()),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(ColorBlendState::new(subpass.num_color_attachments())),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState::default(),
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -31,7 +31,7 @@ use vulkano::{
memory::allocator::{MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::ColorBlendState,
color_blend::{ColorBlendAttachmentState, ColorBlendState},
input_assembly::InputAssemblyState,
multisample::MultisampleState,
rasterization::RasterizationState,
@ -40,7 +40,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo,
DynamicState, GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo,
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{
@ -253,10 +253,14 @@ fn main() {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(InputAssemblyState::default()),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState::default()),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(ColorBlendState::new(subpass.num_color_attachments())),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState::default(),
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -22,7 +22,9 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::{AttachmentBlend, BlendFactor, BlendOp, ColorBlendState},
color_blend::{
AttachmentBlend, BlendFactor, BlendOp, ColorBlendAttachmentState, ColorBlendState,
},
input_assembly::InputAssemblyState,
multisample::MultisampleState,
rasterization::RasterizationState,
@ -31,7 +33,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
PipelineShaderStageCreateInfo,
},
render_pass::Subpass,
@ -118,21 +120,24 @@ impl AmbientLightingSystem {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(InputAssemblyState::default()),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState::default()),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(
ColorBlendState::new(subpass.num_color_attachments()).blend(
AttachmentBlend {
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState {
blend: Some(AttachmentBlend {
color_blend_op: BlendOp::Add,
src_color_blend_factor: BlendFactor::One,
dst_color_blend_factor: BlendFactor::One,
alpha_blend_op: BlendOp::Max,
src_alpha_blend_factor: BlendFactor::One,
dst_alpha_blend_factor: BlendFactor::One,
},
),
),
}),
..Default::default()
},
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.clone().into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -23,7 +23,9 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::{AttachmentBlend, BlendFactor, BlendOp, ColorBlendState},
color_blend::{
AttachmentBlend, BlendFactor, BlendOp, ColorBlendAttachmentState, ColorBlendState,
},
input_assembly::InputAssemblyState,
multisample::MultisampleState,
rasterization::RasterizationState,
@ -32,7 +34,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
PipelineShaderStageCreateInfo,
},
render_pass::Subpass,
@ -119,21 +121,24 @@ impl DirectionalLightingSystem {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(InputAssemblyState::default()),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState::default()),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(
ColorBlendState::new(subpass.num_color_attachments()).blend(
AttachmentBlend {
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState {
blend: Some(AttachmentBlend {
color_blend_op: BlendOp::Add,
src_color_blend_factor: BlendFactor::One,
dst_color_blend_factor: BlendFactor::One,
alpha_blend_op: BlendOp::Max,
src_alpha_blend_factor: BlendFactor::One,
dst_alpha_blend_factor: BlendFactor::One,
},
),
),
}),
..Default::default()
},
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.clone().into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -23,7 +23,9 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::{AttachmentBlend, BlendFactor, BlendOp, ColorBlendState},
color_blend::{
AttachmentBlend, BlendFactor, BlendOp, ColorBlendAttachmentState, ColorBlendState,
},
input_assembly::InputAssemblyState,
multisample::MultisampleState,
rasterization::RasterizationState,
@ -32,7 +34,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
PipelineShaderStageCreateInfo,
},
render_pass::Subpass,
@ -118,21 +120,24 @@ impl PointLightingSystem {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(InputAssemblyState::default()),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState::default()),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(
ColorBlendState::new(subpass.num_color_attachments()).blend(
AttachmentBlend {
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState {
blend: Some(AttachmentBlend {
color_blend_op: BlendOp::Add,
src_color_blend_factor: BlendFactor::One,
dst_color_blend_factor: BlendFactor::One,
alpha_blend_op: BlendOp::Max,
src_alpha_blend_factor: BlendFactor::One,
dst_alpha_blend_factor: BlendFactor::One,
},
),
),
}),
..Default::default()
},
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.clone().into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -18,8 +18,8 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::ColorBlendState,
depth_stencil::DepthStencilState,
color_blend::{ColorBlendAttachmentState, ColorBlendState},
depth_stencil::{DepthState, DepthStencilState},
input_assembly::InputAssemblyState,
multisample::MultisampleState,
rasterization::RasterizationState,
@ -28,7 +28,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo,
DynamicState, GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo,
},
render_pass::Subpass,
};
@ -107,11 +107,18 @@ impl TriangleDrawSystem {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(InputAssemblyState::default()),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState::default()),
depth_stencil_state: Some(DepthStencilState::simple_depth_test()),
depth_stencil_state: Some(DepthStencilState {
depth: Some(DepthState::simple()),
..Default::default()
}),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(ColorBlendState::new(subpass.num_color_attachments())),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState::default(),
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.clone().into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -48,7 +48,7 @@ mod linux {
},
pipeline::{
graphics::{
color_blend::ColorBlendState,
color_blend::{AttachmentBlend, ColorBlendAttachmentState, ColorBlendState},
input_assembly::{InputAssemblyState, PrimitiveTopology},
multisample::MultisampleState,
rasterization::RasterizationState,
@ -57,7 +57,7 @@ mod linux {
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
PipelineShaderStageCreateInfo,
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
@ -688,15 +688,21 @@ mod linux {
GraphicsPipelineCreateInfo {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(
InputAssemblyState::new().topology(PrimitiveTopology::TriangleStrip),
),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
input_assembly_state: Some(InputAssemblyState {
topology: PrimitiveTopology::TriangleStrip,
..Default::default()
}),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState::default()),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(
ColorBlendState::new(subpass.num_color_attachments()).blend_alpha(),
),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState {
blend: Some(AttachmentBlend::alpha()),
..Default::default()
},
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -32,7 +32,7 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::ColorBlendState,
color_blend::{AttachmentBlend, ColorBlendAttachmentState, ColorBlendState},
input_assembly::{InputAssemblyState, PrimitiveTopology},
multisample::MultisampleState,
rasterization::RasterizationState,
@ -41,7 +41,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
PipelineShaderStageCreateInfo,
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
@ -363,15 +363,21 @@ fn main() {
GraphicsPipelineCreateInfo {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(
InputAssemblyState::new().topology(PrimitiveTopology::TriangleStrip),
),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
input_assembly_state: Some(InputAssemblyState {
topology: PrimitiveTopology::TriangleStrip,
..Default::default()
}),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState::default()),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(
ColorBlendState::new(subpass.num_color_attachments()).blend_alpha(),
),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState {
blend: Some(AttachmentBlend::alpha()),
..Default::default()
},
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -31,7 +31,7 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::ColorBlendState,
color_blend::{AttachmentBlend, ColorBlendAttachmentState, ColorBlendState},
input_assembly::{InputAssemblyState, PrimitiveTopology},
multisample::MultisampleState,
rasterization::RasterizationState,
@ -40,7 +40,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
PipelineShaderStageCreateInfo,
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
@ -311,15 +311,21 @@ fn main() {
GraphicsPipelineCreateInfo {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(
InputAssemblyState::new().topology(PrimitiveTopology::TriangleStrip),
),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
input_assembly_state: Some(InputAssemblyState {
topology: PrimitiveTopology::TriangleStrip,
..Default::default()
}),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState::default()),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(
ColorBlendState::new(subpass.num_color_attachments()).blend_alpha(),
),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState {
blend: Some(AttachmentBlend::alpha()),
..Default::default()
},
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -40,7 +40,7 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::ColorBlendState,
color_blend::{AttachmentBlend, ColorBlendAttachmentState, ColorBlendState},
input_assembly::{InputAssemblyState, PrimitiveTopology},
multisample::MultisampleState,
rasterization::RasterizationState,
@ -49,7 +49,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
PipelineShaderStageCreateInfo,
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
@ -329,15 +329,21 @@ fn main() {
GraphicsPipelineCreateInfo {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(
InputAssemblyState::new().topology(PrimitiveTopology::TriangleStrip),
),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
input_assembly_state: Some(InputAssemblyState {
topology: PrimitiveTopology::TriangleStrip,
..Default::default()
}),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState::default()),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(
ColorBlendState::new(subpass.num_color_attachments()).blend_alpha(),
),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState {
blend: Some(AttachmentBlend::alpha()),
..Default::default()
},
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -46,7 +46,7 @@ use vulkano::{
pipeline::{
compute::ComputePipelineCreateInfo,
graphics::{
color_blend::ColorBlendState,
color_blend::{ColorBlendAttachmentState, ColorBlendState},
input_assembly::InputAssemblyState,
multisample::MultisampleState,
rasterization::RasterizationState,
@ -55,8 +55,8 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
ComputePipeline, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
PipelineShaderStageCreateInfo,
ComputePipeline, DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint,
PipelineLayout, PipelineShaderStageCreateInfo,
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
single_pass_renderpass,
@ -346,10 +346,14 @@ fn main() {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(InputAssemblyState::default()),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState::default()),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(ColorBlendState::new(subpass.num_color_attachments())),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState::default(),
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -28,7 +28,7 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::ColorBlendState,
color_blend::{ColorBlendAttachmentState, ColorBlendState},
input_assembly::InputAssemblyState,
multisample::MultisampleState,
rasterization::RasterizationState,
@ -37,7 +37,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo,
DynamicState, GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo,
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
single_pass_renderpass,
@ -323,10 +323,14 @@ fn main() {
// types are expected to be used.
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(InputAssemblyState::default()),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState::default()),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(ColorBlendState::new(subpass.num_color_attachments())),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState::default(),
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -25,7 +25,7 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::ColorBlendState,
color_blend::{ColorBlendAttachmentState, ColorBlendState},
input_assembly::InputAssemblyState,
multisample::MultisampleState,
rasterization::RasterizationState,
@ -34,7 +34,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
PipelineShaderStageCreateInfo,
},
render_pass::Subpass,
@ -155,10 +155,14 @@ impl PixelsDrawPipeline {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(InputAssemblyState::default()),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState::default()),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(ColorBlendState::new(subpass.num_color_attachments())),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState::default(),
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.clone().into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -79,7 +79,7 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::ColorBlendState,
color_blend::{ColorBlendAttachmentState, ColorBlendState},
input_assembly::InputAssemblyState,
multisample::MultisampleState,
rasterization::RasterizationState,
@ -88,7 +88,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo,
DynamicState, GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo,
},
render_pass::{Framebuffer, FramebufferCreateInfo, Subpass},
sync::GpuFuture,
@ -345,13 +345,17 @@ fn main() {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(InputAssemblyState::default()),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState::default()),
multisample_state: Some(MultisampleState {
rasterization_samples: subpass.num_samples().unwrap(),
..Default::default()
}),
color_blend_state: Some(ColorBlendState::new(subpass.num_color_attachments())),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState::default(),
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -32,7 +32,7 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::ColorBlendState,
color_blend::{ColorBlendAttachmentState, ColorBlendState},
input_assembly::InputAssemblyState,
multisample::MultisampleState,
rasterization::RasterizationState,
@ -41,7 +41,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo,
DynamicState, GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo,
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{
@ -291,10 +291,14 @@ fn main() {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(InputAssemblyState::default()),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState::default()),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(ColorBlendState::new(subpass.num_color_attachments())),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState::default(),
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -26,7 +26,7 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter},
pipeline::{
graphics::{
color_blend::ColorBlendState,
color_blend::{ColorBlendAttachmentState, ColorBlendState},
input_assembly::InputAssemblyState,
multisample::MultisampleState,
rasterization::RasterizationState,
@ -35,7 +35,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
PipelineShaderStageCreateInfo,
},
render_pass::Subpass,
@ -151,10 +151,14 @@ impl PixelsDrawPipeline {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(InputAssemblyState::default()),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState::default()),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(ColorBlendState::new(subpass.num_color_attachments())),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState::default(),
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.clone().into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -32,7 +32,7 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::ColorBlendState,
color_blend::{ColorBlendAttachmentState, ColorBlendState},
input_assembly::InputAssemblyState,
multisample::MultisampleState,
rasterization::RasterizationState,
@ -291,16 +291,22 @@ fn main() {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(InputAssemblyState::default()),
viewport_state: Some(ViewportState::viewport_fixed_scissor_irrelevant([
Viewport {
viewport_state: Some(ViewportState {
viewports: [Viewport {
offset: [0.0, 0.0],
extent: [image.extent()[0] as f32, image.extent()[1] as f32],
depth_range: 0.0..=1.0,
},
])),
}]
.into_iter()
.collect(),
..Default::default()
}),
rasterization_state: Some(RasterizationState::default()),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(ColorBlendState::new(subpass.num_color_attachments())),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState::default(),
)),
subpass: Some(subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -28,8 +28,8 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::ColorBlendState,
depth_stencil::DepthStencilState,
color_blend::{ColorBlendAttachmentState, ColorBlendState},
depth_stencil::{DepthState, DepthStencilState},
input_assembly::InputAssemblyState,
multisample::MultisampleState,
rasterization::RasterizationState,
@ -38,7 +38,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo,
DynamicState, GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo,
},
query::{QueryControlFlags, QueryPool, QueryPoolCreateInfo, QueryResultFlags, QueryType},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
@ -332,14 +332,21 @@ fn main() {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(InputAssemblyState::default()),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState::default()),
multisample_state: Some(MultisampleState::default()),
// Enable depth testing, which is needed for occlusion queries to make sense at all. If you
// disable depth testing, every pixel is considered to pass the depth test, so every query
// will return a nonzero result.
depth_stencil_state: Some(DepthStencilState::simple_depth_test()),
color_blend_state: Some(ColorBlendState::new(subpass.num_color_attachments())),
depth_stencil_state: Some(DepthStencilState {
depth: Some(DepthState::simple()),
..Default::default()
}),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState::default(),
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -29,7 +29,7 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::ColorBlendState,
color_blend::{AttachmentBlend, ColorBlendAttachmentState, ColorBlendState},
input_assembly::{InputAssemblyState, PrimitiveTopology},
multisample::MultisampleState,
rasterization::RasterizationState,
@ -38,7 +38,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
PipelineShaderStageCreateInfo,
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
@ -314,15 +314,21 @@ fn main() {
GraphicsPipelineCreateInfo {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(
InputAssemblyState::new().topology(PrimitiveTopology::TriangleStrip),
),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
input_assembly_state: Some(InputAssemblyState {
topology: PrimitiveTopology::TriangleStrip,
..Default::default()
}),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState::default()),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(
ColorBlendState::new(subpass.num_color_attachments()).blend_alpha(),
),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState {
blend: Some(AttachmentBlend::alpha()),
..Default::default()
},
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -37,7 +37,7 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::ColorBlendState,
color_blend::{ColorBlendAttachmentState, ColorBlendState},
input_assembly::InputAssemblyState,
multisample::MultisampleState,
rasterization::{CullMode, FrontFace, RasterizationState},
@ -46,7 +46,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo,
DynamicState, GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo,
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
shader::{ShaderModule, ShaderModuleCreateInfo},
@ -219,14 +219,18 @@ fn main() {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(InputAssemblyState::default()),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
rasterization_state: Some(
RasterizationState::new()
.cull_mode(CullMode::Front)
.front_face(FrontFace::CounterClockwise),
),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState {
cull_mode: CullMode::Front,
front_face: FrontFace::CounterClockwise,
..Default::default()
}),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(ColorBlendState::new(subpass.num_color_attachments())),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState::default(),
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -32,7 +32,7 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::ColorBlendState,
color_blend::{AttachmentBlend, ColorBlendAttachmentState, ColorBlendState},
input_assembly::InputAssemblyState,
multisample::MultisampleState,
rasterization::RasterizationState,
@ -41,7 +41,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
PipelineShaderStageCreateInfo,
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
@ -435,12 +435,17 @@ fn main() {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(InputAssemblyState::default()),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState::default()),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(
ColorBlendState::new(subpass.num_color_attachments()).blend_alpha(),
),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState {
blend: Some(AttachmentBlend::alpha()),
..Default::default()
},
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -32,7 +32,7 @@ use vulkano::{
pipeline::{
compute::ComputePipelineCreateInfo,
graphics::{
color_blend::ColorBlendState,
color_blend::{ColorBlendAttachmentState, ColorBlendState},
input_assembly::{InputAssemblyState, PrimitiveTopology},
multisample::MultisampleState,
rasterization::RasterizationState,
@ -455,13 +455,6 @@ fn main() {
)
.unwrap();
// Fixed viewport.
let viewport = Viewport {
offset: [0.0, 0.0],
extent: [WINDOW_WIDTH as f32, WINDOW_HEIGHT as f32],
depth_range: 0.0..=1.0,
};
// Create a basic graphics pipeline for rendering particles.
let graphics_pipeline = {
let vs = vs::load(device.clone())
@ -494,13 +487,26 @@ fn main() {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
// Vertices will be rendered as a list of points.
input_assembly_state: Some(
InputAssemblyState::new().topology(PrimitiveTopology::PointList),
),
viewport_state: Some(ViewportState::viewport_fixed_scissor_irrelevant([viewport])),
input_assembly_state: Some(InputAssemblyState {
topology: PrimitiveTopology::PointList,
..Default::default()
}),
viewport_state: Some(ViewportState {
viewports: [Viewport {
offset: [0.0, 0.0],
extent: [WINDOW_WIDTH as f32, WINDOW_HEIGHT as f32],
depth_range: 0.0..=1.0,
}]
.into_iter()
.collect(),
..Default::default()
}),
rasterization_state: Some(RasterizationState::default()),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(ColorBlendState::new(subpass.num_color_attachments())),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState::default(),
)),
subpass: Some(subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -32,8 +32,8 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::ColorBlendState,
depth_stencil::DepthStencilState,
color_blend::{ColorBlendAttachmentState, ColorBlendState},
depth_stencil::{DepthState, DepthStencilState},
input_assembly::InputAssemblyState,
multisample::MultisampleState,
rasterization::RasterizationState,
@ -504,17 +504,26 @@ fn window_size_dependent_setup(
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(InputAssemblyState::default()),
viewport_state: Some(ViewportState::viewport_fixed_scissor_irrelevant([
Viewport {
viewport_state: Some(ViewportState {
viewports: [Viewport {
offset: [0.0, 0.0],
extent: [extent[0] as f32, extent[1] as f32],
depth_range: 0.0..=1.0,
},
])),
}]
.into_iter()
.collect(),
..Default::default()
}),
rasterization_state: Some(RasterizationState::default()),
depth_stencil_state: Some(DepthStencilState::simple_depth_test()),
depth_stencil_state: Some(DepthStencilState {
depth: Some(DepthState::simple()),
..Default::default()
}),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(ColorBlendState::new(subpass.num_color_attachments())),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState::default(),
)),
subpass: Some(subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -37,7 +37,7 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::ColorBlendState,
color_blend::{ColorBlendAttachmentState, ColorBlendState},
input_assembly::{InputAssemblyState, PrimitiveTopology},
multisample::MultisampleState,
rasterization::{PolygonMode, RasterizationState},
@ -47,7 +47,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo,
DynamicState, GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo,
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{
@ -373,22 +373,28 @@ fn main() {
GraphicsPipelineCreateInfo {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(
InputAssemblyState::new().topology(PrimitiveTopology::PatchList),
),
tessellation_state: Some(
TessellationState::new()
// Use a patch_control_points of 3, because we want to convert one *triangle*
// into lots of little ones.
// A value of 4 would convert a *rectangle* into lots of little triangles.
.patch_control_points(3),
),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
rasterization_state: Some(
RasterizationState::new().polygon_mode(PolygonMode::Line),
),
input_assembly_state: Some(InputAssemblyState {
topology: PrimitiveTopology::PatchList,
..Default::default()
}),
tessellation_state: Some(TessellationState {
// Use a patch_control_points of 3, because we want to convert one *triangle*
// into lots of little ones.
// A value of 4 would convert a *rectangle* into lots of little triangles.
patch_control_points: 3,
..Default::default()
}),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState {
polygon_mode: PolygonMode::Line,
..Default::default()
}),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(ColorBlendState::new(subpass.num_color_attachments())),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState::default(),
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -31,7 +31,7 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::ColorBlendState,
color_blend::{AttachmentBlend, ColorBlendAttachmentState, ColorBlendState},
input_assembly::{InputAssemblyState, PrimitiveTopology},
multisample::MultisampleState,
rasterization::RasterizationState,
@ -40,7 +40,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
PipelineShaderStageCreateInfo,
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
@ -322,15 +322,21 @@ fn main() {
GraphicsPipelineCreateInfo {
stages: stages.into_iter().collect(),
vertex_input_state: Some(vertex_input_state),
input_assembly_state: Some(
InputAssemblyState::new().topology(PrimitiveTopology::TriangleStrip),
),
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
input_assembly_state: Some(InputAssemblyState {
topology: PrimitiveTopology::TriangleStrip,
..Default::default()
}),
viewport_state: Some(ViewportState::default()),
rasterization_state: Some(RasterizationState::default()),
multisample_state: Some(MultisampleState::default()),
color_blend_state: Some(
ColorBlendState::new(subpass.num_color_attachments()).blend_alpha(),
),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState {
blend: Some(AttachmentBlend::alpha()),
..Default::default()
},
)),
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -37,7 +37,7 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::ColorBlendState,
color_blend::{ColorBlendAttachmentState, ColorBlendState},
input_assembly::InputAssemblyState,
multisample::MultisampleState,
rasterization::RasterizationState,
@ -47,7 +47,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo,
DynamicState, GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo,
},
render_pass::{AttachmentLoadOp, AttachmentStoreOp},
swapchain::{
@ -449,7 +449,7 @@ fn main() {
input_assembly_state: Some(InputAssemblyState::default()),
// How primitives are transformed and clipped to fit the framebuffer.
// We use a resizable viewport, set to draw over the entire window.
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
viewport_state: Some(ViewportState::default()),
// How polygons are culled and converted into a raster of pixels.
// The default value does not perform any culling.
rasterization_state: Some(RasterizationState::default()),
@ -458,9 +458,14 @@ fn main() {
multisample_state: Some(MultisampleState::default()),
// How pixel values are combined with the values already present in the framebuffer.
// The default value overwrites the old value with the new one, without any blending.
color_blend_state: Some(ColorBlendState::new(
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.color_attachment_formats.len() as u32,
ColorBlendAttachmentState::default(),
)),
// Dynamic states allows us to specify parts of the pipeline settings when
// recording the command buffer, before we perform drawing.
// Here, we specify that the viewport should be dynamic.
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -32,7 +32,7 @@ use vulkano::{
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
pipeline::{
graphics::{
color_blend::ColorBlendState,
color_blend::{ColorBlendAttachmentState, ColorBlendState},
input_assembly::InputAssemblyState,
multisample::MultisampleState,
rasterization::RasterizationState,
@ -41,7 +41,7 @@ use vulkano::{
GraphicsPipelineCreateInfo,
},
layout::PipelineDescriptorSetLayoutCreateInfo,
GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo,
DynamicState, GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo,
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{
@ -446,7 +446,7 @@ fn main() {
input_assembly_state: Some(InputAssemblyState::default()),
// How primitives are transformed and clipped to fit the framebuffer.
// We use a resizable viewport, set to draw over the entire window.
viewport_state: Some(ViewportState::viewport_dynamic_scissor_irrelevant()),
viewport_state: Some(ViewportState::default()),
// How polygons are culled and converted into a raster of pixels.
// The default value does not perform any culling.
rasterization_state: Some(RasterizationState::default()),
@ -455,7 +455,14 @@ fn main() {
multisample_state: Some(MultisampleState::default()),
// How pixel values are combined with the values already present in the framebuffer.
// The default value overwrites the old value with the new one, without any blending.
color_blend_state: Some(ColorBlendState::new(subpass.num_color_attachments())),
color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(),
ColorBlendAttachmentState::default(),
)),
// Dynamic states allows us to specify parts of the pipeline settings when
// recording the command buffer, before we perform drawing.
// Here, we specify that the viewport should be dynamic.
dynamic_state: [DynamicState::Viewport].into_iter().collect(),
subpass: Some(subpass.into()),
..GraphicsPipelineCreateInfo::layout(layout)
},

View File

@ -575,7 +575,7 @@ fn extensions_common_output(struct_name: Ident, members: &[ExtensionsMember]) ->
}
/// Returns an `Extensions` object with none of the members set.
#[deprecated(since = "0.31.0", note = "Use `empty` instead.")]
#[deprecated(since = "0.31.0", note = "use `empty` instead")]
#[inline]
pub const fn none() -> Self {
Self::empty()
@ -594,7 +594,7 @@ fn extensions_common_output(struct_name: Ident, members: &[ExtensionsMember]) ->
}
/// Returns whether all members in `other` are set in `self`.
#[deprecated(since = "0.31.0", note = "Use `contains` instead.")]
#[deprecated(since = "0.31.0", note = "use `contains` instead")]
#[inline]
pub const fn is_superset_of(&self, other: &Self) -> bool {
self.contains(other)

View File

@ -306,7 +306,7 @@ fn features_output(members: &[FeaturesMember]) -> TokenStream {
}
/// Returns an `Features` object with none of the members set.
#[deprecated(since = "0.31.0", note = "Use `empty` instead.")]
#[deprecated(since = "0.31.0", note = "use `empty` instead")]
#[inline]
pub const fn none() -> Self {
Self::empty()
@ -334,7 +334,7 @@ fn features_output(members: &[FeaturesMember]) -> TokenStream {
}
/// Returns whether all members in `other` are set in `self`.
#[deprecated(since = "0.31.0", note = "Use `contains` instead.")]
#[deprecated(since = "0.31.0", note = "use `contains` instead")]
#[inline]
pub const fn is_superset_of(&self, other: &Self) -> bool {
self.contains(other)

View File

@ -31,7 +31,7 @@ use crate::{
color_blend::LogicOp,
depth_stencil::{CompareOp, StencilOps},
input_assembly::PrimitiveTopology,
rasterization::{CullMode, DepthBias, FrontFace, LineStipple},
rasterization::{CullMode, DepthBiasState, FrontFace, LineStipple},
subpass::PipelineRenderingCreateInfo,
viewport::{Scissor, Viewport},
},
@ -1337,7 +1337,7 @@ pub(in crate::command_buffer) struct CommandBufferBuilderState {
pub(in crate::command_buffer) blend_constants: Option<[f32; 4]>,
pub(in crate::command_buffer) color_write_enable: Option<SmallVec<[bool; 4]>>,
pub(in crate::command_buffer) cull_mode: Option<CullMode>,
pub(in crate::command_buffer) depth_bias: Option<DepthBias>,
pub(in crate::command_buffer) depth_bias: Option<DepthBiasState>,
pub(in crate::command_buffer) depth_bias_enable: Option<bool>,
pub(in crate::command_buffer) depth_bounds: Option<RangeInclusive<f32>>,
pub(in crate::command_buffer) depth_bounds_test_enable: Option<bool>,
@ -1392,8 +1392,8 @@ impl CommandBufferBuilderState {
DynamicState::DepthTestEnable => self.depth_test_enable = None,
DynamicState::DepthWriteEnable => self.depth_write_enable = None,
DynamicState::DiscardRectangle => self.discard_rectangle.clear(),
DynamicState::ExclusiveScissor => (), // TODO;
DynamicState::FragmentShadingRate => (), // TODO:
// DynamicState::ExclusiveScissor => todo!(),
// DynamicState::FragmentShadingRate => todo!(),
DynamicState::FrontFace => self.front_face = None,
DynamicState::LineStipple => self.line_stipple = None,
DynamicState::LineWidth => self.line_width = None,
@ -1402,8 +1402,8 @@ impl CommandBufferBuilderState {
DynamicState::PrimitiveRestartEnable => self.primitive_restart_enable = None,
DynamicState::PrimitiveTopology => self.primitive_topology = None,
DynamicState::RasterizerDiscardEnable => self.rasterizer_discard_enable = None,
DynamicState::RayTracingPipelineStackSize => (), // TODO:
DynamicState::SampleLocations => (), // TODO:
// DynamicState::RayTracingPipelineStackSize => todo!(),
// DynamicState::SampleLocations => todo!(),
DynamicState::Scissor => self.scissor.clear(),
DynamicState::ScissorWithCount => self.scissor_with_count = None,
DynamicState::StencilCompareMask => self.stencil_compare_mask = Default::default(),
@ -1411,44 +1411,44 @@ impl CommandBufferBuilderState {
DynamicState::StencilReference => self.stencil_reference = Default::default(),
DynamicState::StencilTestEnable => self.stencil_test_enable = None,
DynamicState::StencilWriteMask => self.stencil_write_mask = Default::default(),
DynamicState::VertexInput => (), // TODO:
DynamicState::VertexInputBindingStride => (), // TODO:
// DynamicState::VertexInput => todo!(),
// DynamicState::VertexInputBindingStride => todo!(),
DynamicState::Viewport => self.viewport.clear(),
DynamicState::ViewportCoarseSampleOrder => (), // TODO:
DynamicState::ViewportShadingRatePalette => (), // TODO:
DynamicState::ViewportWScaling => (), // TODO:
// DynamicState::ViewportCoarseSampleOrder => todo!(),
// DynamicState::ViewportShadingRatePalette => todo!(),
// DynamicState::ViewportWScaling => todo!(),
DynamicState::ViewportWithCount => self.viewport_with_count = None,
DynamicState::TessellationDomainOrigin => (), // TODO:
DynamicState::DepthClampEnable => (), // TODO:
DynamicState::PolygonMode => (), // TODO:
DynamicState::RasterizationSamples => (), // TODO:
DynamicState::SampleMask => (), // TODO:
DynamicState::AlphaToCoverageEnable => (), // TODO:
DynamicState::AlphaToOneEnable => (), // TODO:
DynamicState::LogicOpEnable => (), // TODO:
DynamicState::ColorBlendEnable => (), // TODO:
DynamicState::ColorBlendEquation => (), // TODO:
DynamicState::ColorWriteMask => (), // TODO:
DynamicState::RasterizationStream => (), // TODO:
DynamicState::ConservativeRasterizationMode => (), // TODO:
DynamicState::ExtraPrimitiveOverestimationSize => (), // TODO:
DynamicState::DepthClipEnable => (), // TODO:
DynamicState::SampleLocationsEnable => (), // TODO:
DynamicState::ColorBlendAdvanced => (), // TODO:
DynamicState::ProvokingVertexMode => (), // TODO:
DynamicState::LineRasterizationMode => (), // TODO:
DynamicState::LineStippleEnable => (), // TODO:
DynamicState::DepthClipNegativeOneToOne => (), // TODO:
DynamicState::ViewportWScalingEnable => (), // TODO:
DynamicState::ViewportSwizzle => (), // TODO:
DynamicState::CoverageToColorEnable => (), // TODO:
DynamicState::CoverageToColorLocation => (), // TODO:
DynamicState::CoverageModulationMode => (), // TODO:
DynamicState::CoverageModulationTableEnable => (), // TODO:
DynamicState::CoverageModulationTable => (), // TODO:
DynamicState::ShadingRateImageEnable => (), // TODO:
DynamicState::RepresentativeFragmentTestEnable => (), // TODO:
DynamicState::CoverageReductionMode => (), // TODO:
// DynamicState::TessellationDomainOrigin => todo!(),
// DynamicState::DepthClampEnable => todo!(),
// DynamicState::PolygonMode => todo!(),
// DynamicState::RasterizationSamples => todo!(),
// DynamicState::SampleMask => todo!(),
// DynamicState::AlphaToCoverageEnable => todo!(),
// DynamicState::AlphaToOneEnable => todo!(),
// DynamicState::LogicOpEnable => todo!(),
// DynamicState::ColorBlendEnable => todo!(),
// DynamicState::ColorBlendEquation => todo!(),
// DynamicState::ColorWriteMask => todo!(),
// DynamicState::RasterizationStream => todo!(),
// DynamicState::ConservativeRasterizationMode => todo!(),
// DynamicState::ExtraPrimitiveOverestimationSize => todo!(),
// DynamicState::DepthClipEnable => todo!(),
// DynamicState::SampleLocationsEnable => todo!(),
// DynamicState::ColorBlendAdvanced => todo!(),
// DynamicState::ProvokingVertexMode => todo!(),
// DynamicState::LineRasterizationMode => todo!(),
// DynamicState::LineStippleEnable => todo!(),
// DynamicState::DepthClipNegativeOneToOne => todo!(),
// DynamicState::ViewportWScalingEnable => todo!(),
// DynamicState::ViewportSwizzle => todo!(),
// DynamicState::CoverageToColorEnable => todo!(),
// DynamicState::CoverageToColorLocation => todo!(),
// DynamicState::CoverageModulationMode => todo!(),
// DynamicState::CoverageModulationTableEnable => todo!(),
// DynamicState::CoverageModulationTable => todo!(),
// DynamicState::ShadingRateImageEnable => todo!(),
// DynamicState::RepresentativeFragmentTestEnable => todo!(),
// DynamicState::CoverageReductionMode => todo!(),
}
}
}

View File

@ -226,12 +226,8 @@ where
) -> &mut Self {
// Reset any states that are fixed in the new pipeline. The pipeline bind command will
// overwrite these states.
self.builder_state.reset_dynamic_states(
pipeline
.dynamic_states()
.filter(|(_, d)| !d) // not dynamic
.map(|(s, _)| s),
);
self.builder_state
.reset_dynamic_states(pipeline.fixed_state().iter().copied());
self.builder_state.pipeline_graphics = Some(pipeline.clone());
self.add_command(
"bind_pipeline_graphics",

View File

@ -18,7 +18,7 @@ use crate::{
color_blend::LogicOp,
depth_stencil::{CompareOp, StencilFaces, StencilOp, StencilOps},
input_assembly::PrimitiveTopology,
rasterization::{CullMode, DepthBias, FrontFace, LineStipple},
rasterization::{CullMode, DepthBiasState, FrontFace, LineStipple},
viewport::{Scissor, Viewport},
},
DynamicState,
@ -44,9 +44,7 @@ where
.builder_state
.pipeline_graphics
.as_ref()
.map_or(false, |pipeline| {
matches!(pipeline.dynamic_state(state), Some(false))
})
.map_or(false, |pipeline| pipeline.fixed_state().contains(&state))
{
return Err(Box::new(ValidationError {
problem: "the state for this value in the currently bound graphics pipeline \
@ -217,7 +215,7 @@ where
clamp: f32,
slope_factor: f32,
) -> &mut Self {
self.builder_state.depth_bias = Some(DepthBias {
self.builder_state.depth_bias = Some(DepthBiasState {
constant_factor,
clamp,
slope_factor,

View File

@ -29,7 +29,7 @@ use crate::{
input_assembly::PrimitiveTopology, subpass::PipelineSubpassType,
vertex_input::VertexInputRate,
},
DynamicState, GraphicsPipeline, PartialStateMode, Pipeline, PipelineLayout,
DynamicState, GraphicsPipeline, Pipeline, PipelineLayout,
},
shader::{DescriptorBindingRequirements, DescriptorIdentifier, ShaderStage, ShaderStages},
sync::{PipelineStageAccess, PipelineStageAccessFlags},
@ -1519,11 +1519,7 @@ where
) -> Result<(), Box<ValidationError>> {
let device = pipeline.device();
for dynamic_state in pipeline
.dynamic_states()
.filter(|(_, d)| *d)
.map(|(s, _)| s)
{
for dynamic_state in pipeline.dynamic_state().iter().copied() {
match dynamic_state {
DynamicState::BlendConstants => {
if self.builder_state.blend_constants.is_none() {
@ -1534,7 +1530,8 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-07835"),
..Default::default()
}));
@ -1551,7 +1548,8 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-07749"),
..Default::default()
}));
@ -1579,7 +1577,8 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-07840"),
..Default::default()
}));
@ -1594,7 +1593,8 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-07834"),
..Default::default()
}));
@ -1609,7 +1609,8 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-04877"),
..Default::default()
}));
@ -1624,7 +1625,8 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-07836"),
..Default::default()
}));
@ -1639,7 +1641,8 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-07846"),
..Default::default()
}));
@ -1654,7 +1657,8 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-07845"),
..Default::default()
}));
@ -1669,7 +1673,8 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-07843"),
..Default::default()
}));
@ -1684,20 +1689,17 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-07844"),
..Default::default()
}));
}
}
DynamicState::DiscardRectangle => {
let discard_rectangle_count =
match pipeline.discard_rectangle_state().unwrap().rectangles {
PartialStateMode::Dynamic(count) => count,
_ => unreachable!(),
};
for num in 0..discard_rectangle_count {
for num in
0..pipeline.discard_rectangle_state().unwrap().rectangles.len() as u32
{
if !self.builder_state.discard_rectangle.contains_key(&num) {
return Err(Box::new(ValidationError {
problem: format!(
@ -1707,15 +1709,16 @@ where
it was overwritten by a more recent \
`bind_pipeline_graphics` command",
dynamic_state, num,
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-07751"),
..Default::default()
}));
}
}
}
DynamicState::ExclusiveScissor => todo!(),
DynamicState::FragmentShadingRate => todo!(),
// DynamicState::ExclusiveScissor => todo!(),
// DynamicState::FragmentShadingRate => todo!(),
DynamicState::FrontFace => {
if self.builder_state.front_face.is_none() {
return Err(Box::new(ValidationError {
@ -1725,7 +1728,8 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-0784"),
..Default::default()
}));
@ -1740,7 +1744,8 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-07849"),
..Default::default()
}));
@ -1755,7 +1760,8 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-07833"),
..Default::default()
}));
@ -1770,7 +1776,8 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "logicOp-04878"),
..Default::default()
}));
@ -1785,7 +1792,8 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-04875"),
..Default::default()
}));
@ -1803,31 +1811,34 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-04879"),
..Default::default()
}));
};
if primitive_restart_enable {
let topology = match pipeline.input_assembly_state().topology {
PartialStateMode::Fixed(topology) => topology,
PartialStateMode::Dynamic(_) => {
if let Some(topology) = self.builder_state.primitive_topology {
topology
} else {
return Err(Box::new(ValidationError {
problem: "the currently bound graphics pipeline requires \
the `DynamicState::PrimitiveTopology` dynamic state, \
but this state was either not set, or it was \
overwritten by a more recent `bind_pipeline_graphics` \
command"
.into(),
vuids: vuids!(vuid_type, "None-07842"),
..Default::default()
}));
}
let topology = if pipeline
.dynamic_state()
.contains(&DynamicState::PrimitiveTopology)
{
if let Some(topology) = self.builder_state.primitive_topology {
topology
} else {
return Err(Box::new(ValidationError {
problem: "the currently bound graphics pipeline requires \
the `DynamicState::PrimitiveTopology` dynamic state, \
but this state was either not set, or it was \
overwritten by a more recent `bind_pipeline_graphics` \
command"
.into(),
vuids: vuids!(vuid_type, "None-07842"),
..Default::default()
}));
}
} else {
pipeline.input_assembly_state().topology
};
match topology {
@ -1843,7 +1854,9 @@ where
dynamic primitive topology is \
`PrimitiveTopology::*List`"
.into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature("primitive_topology_list_restart")])]),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
Requires::Feature("primitive_topology_list_restart"),
])]),
// vuids?
..Default::default()
}));
@ -1860,7 +1873,11 @@ where
dynamic primitive topology is \
`PrimitiveTopology::PatchList`"
.into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature("primitive_topology_patch_list_restart")])]),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
Requires::Feature(
"primitive_topology_patch_list_restart",
),
])]),
// vuids?
..Default::default()
}));
@ -1881,7 +1898,8 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-07842"),
..Default::default()
}));
@ -1896,7 +1914,8 @@ where
includes tessellation shader stages, but the dynamic \
primitive topology is not `PrimitiveTopology::PatchList`",
dynamic_state
).into(),
)
.into(),
// vuids?
..Default::default()
}));
@ -1910,7 +1929,8 @@ where
does not include tessellation shader stages, but the dynamic \
primitive topology is `PrimitiveTopology::PatchList`",
dynamic_state
).into(),
)
.into(),
// vuids?
..Default::default()
}));
@ -1919,13 +1939,39 @@ where
let properties = device.physical_device().properties();
if !properties.dynamic_primitive_topology_unrestricted.unwrap_or(false) {
let required_topology_class = match pipeline.input_assembly_state().topology {
PartialStateMode::Dynamic(topology_class) => topology_class,
_ => unreachable!(),
};
if !properties
.dynamic_primitive_topology_unrestricted
.unwrap_or(false)
{
let is_same_topology_class = matches!(
(topology, pipeline.input_assembly_state().topology),
(PrimitiveTopology::PointList, PrimitiveTopology::PointList)
| (
PrimitiveTopology::LineList
| PrimitiveTopology::LineStrip
| PrimitiveTopology::LineListWithAdjacency
| PrimitiveTopology::LineStripWithAdjacency,
PrimitiveTopology::LineList
| PrimitiveTopology::LineStrip
| PrimitiveTopology::LineListWithAdjacency
| PrimitiveTopology::LineStripWithAdjacency,
)
| (
PrimitiveTopology::TriangleList
| PrimitiveTopology::TriangleStrip
| PrimitiveTopology::TriangleFan
| PrimitiveTopology::TriangleListWithAdjacency
| PrimitiveTopology::TriangleStripWithAdjacency,
PrimitiveTopology::TriangleList
| PrimitiveTopology::TriangleStrip
| PrimitiveTopology::TriangleFan
| PrimitiveTopology::TriangleListWithAdjacency
| PrimitiveTopology::TriangleStripWithAdjacency,
)
| (PrimitiveTopology::PatchList, PrimitiveTopology::PatchList)
);
if topology.class() != required_topology_class {
if !is_same_topology_class {
return Err(Box::new(ValidationError {
problem: format!(
"the currently bound graphics pipeline requires the \
@ -1935,8 +1981,12 @@ where
to the same topology class as the topology that the \
graphics pipeline was created with",
dynamic_state
).into(),
vuids: vuids!(vuid_type, "dynamicPrimitiveTopologyUnrestricted-07500"),
)
.into(),
vuids: vuids!(
vuid_type,
"dynamicPrimitiveTopologyUnrestricted-07500"
),
..Default::default()
}));
}
@ -1953,41 +2003,48 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-04876"),
..Default::default()
}));
}
}
DynamicState::RayTracingPipelineStackSize => unreachable!(
"RayTracingPipelineStackSize dynamic state should not occur on a graphics pipeline"
),
DynamicState::SampleLocations => todo!(),
// DynamicState::RayTracingPipelineStackSize => unreachable!(
// "RayTracingPipelineStackSize dynamic state should not occur on a graphics pipeline"
// ),
// DynamicState::SampleLocations => todo!(),
DynamicState::Scissor => {
for num in 0..pipeline.viewport_state().unwrap().count().unwrap() {
let viewport_state = pipeline.viewport_state().unwrap();
for num in 0..viewport_state.scissors.len() as u32 {
if !self.builder_state.scissor.contains_key(&num) {
return Err(Box::new(ValidationError {
problem: format!(
"the currently bound graphics pipeline requires the \
`DynamicState::{:?}` dynamic state, but \
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
vuids: vuids!(vuid_type, "None-07832"),
..Default::default()
}));
problem: format!(
"the currently bound graphics pipeline requires the \
`DynamicState::{:?}` dynamic state, but \
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
)
.into(),
vuids: vuids!(vuid_type, "None-07832"),
..Default::default()
}));
}
}
}
DynamicState::ScissorWithCount => {
if let Some(scissors) = &self.builder_state.scissor_with_count {
if let Some(viewport_count) = pipeline.viewport_state().unwrap().count() {
let viewport_state = pipeline.viewport_state().unwrap();
let viewport_count = viewport_state.viewports.len() as u32;
let scissor_count = scissors.len() as u32;
if viewport_count != 0 {
// Check if the counts match, but only if the viewport count is fixed.
// If the viewport count is also dynamic, then the
// DynamicState::ViewportWithCount match arm will handle it.
if viewport_count != scissors.len() as u32 {
if viewport_count != scissor_count {
return Err(Box::new(ValidationError {
problem: "the currently bound graphics pipeline requires the \
`DynamicState::ScissorWithCount` dynamic state, and \
@ -2008,7 +2065,8 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "scissorCount-03418", "viewportCount-03419"),
..Default::default()
}));
@ -2025,9 +2083,10 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-07837"),
..Default::default()
..Default::default() //
}));
}
}
@ -2042,7 +2101,8 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-07848"),
..Default::default()
}));
@ -2059,7 +2119,8 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-07839"),
..Default::default()
}));
@ -2074,7 +2135,8 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-07847"),
..Default::default()
}));
@ -2091,36 +2153,90 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "None-07838"),
..Default::default()
}));
}
}
DynamicState::VertexInput => todo!(),
DynamicState::VertexInputBindingStride => todo!(),
// DynamicState::VertexInput => todo!(),
// DynamicState::VertexInputBindingStride => todo!(),
DynamicState::Viewport => {
for num in 0..pipeline.viewport_state().unwrap().count().unwrap() {
let viewport_state = pipeline.viewport_state().unwrap();
for num in 0..viewport_state.viewports.len() as u32 {
if !self.builder_state.viewport.contains_key(&num) {
return Err(Box::new(ValidationError {
problem: format!(
"the currently bound graphics pipeline requires the \
`DynamicState::{:?}` dynamic state, but \
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
vuids: vuids!(vuid_type, "None-07831"),
..Default::default()
}));
problem: format!(
"the currently bound graphics pipeline requires the \
`DynamicState::{:?}` dynamic state, but \
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
)
.into(),
vuids: vuids!(vuid_type, "None-07831"),
..Default::default()
}));
}
}
}
DynamicState::ViewportCoarseSampleOrder => todo!(),
DynamicState::ViewportShadingRatePalette => todo!(),
// DynamicState::ViewportCoarseSampleOrder => todo!(),
// DynamicState::ViewportShadingRatePalette => todo!(),
DynamicState::ViewportWithCount => {
let viewport_count = if let Some(viewports) = &self.builder_state.viewport_with_count {
viewports.len() as u32
if let Some(viewports) = &self.builder_state.viewport_with_count {
let viewport_state = pipeline.viewport_state().unwrap();
let scissor_count = viewport_state.scissors.len() as u32;
let viewport_count = viewports.len() as u32;
if scissor_count != 0 {
if viewport_count != scissor_count {
return Err(Box::new(ValidationError {
problem: "the currently bound graphics pipeline requires the \
`DynamicState::ViewportWithCount` dynamic state, and \
not the `DynamicState::ScissorWithCount` dynamic state, \
but the dynamic scissor count is not equal to the scissor \
count specified when creating the pipeline"
.into(),
vuids: vuids!(vuid_type, "viewportCount-03417"),
..Default::default()
}));
}
} else {
if let Some(scissors) = &self.builder_state.scissor_with_count {
if viewport_count != scissors.len() as u32 {
return Err(Box::new(ValidationError {
problem:
"the currently bound graphics pipeline requires both \
the `DynamicState::ViewportWithCount` and the \
`DynamicState::ScissorWithCount` dynamic states, but \
the dynamic scissor count is not equal to the \
dynamic scissor count "
.into(),
vuids: vuids!(vuid_type, "viewportCount-03419"),
..Default::default()
}));
}
} else {
return Err(Box::new(ValidationError {
problem: format!(
"the currently bound graphics pipeline requires the \
`DynamicState::{:?}` dynamic state, but \
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
)
.into(),
vuids: vuids!(
vuid_type,
"scissorCount-03418",
"viewportCount-03419"
),
..Default::default()
}));
}
}
} else {
return Err(Box::new(ValidationError {
problem: format!(
@ -2129,54 +2245,11 @@ where
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
)
.into(),
vuids: vuids!(vuid_type, "viewportCount-03417", "viewportCount-03419"),
..Default::default()
}));
};
if let Some(scissor_count) =
pipeline.viewport_state().unwrap().count()
{
if viewport_count != scissor_count {
return Err(Box::new(ValidationError {
problem: "the currently bound graphics pipeline requires the \
`DynamicState::ViewportWithCount` dynamic state, and \
not the `DynamicState::ScissorWithCount` dynamic state, but \
the dynamic scissor count is not equal to the scissor count \
specified when creating the pipeline"
.into(),
vuids: vuids!(vuid_type, "viewportCount-03417"),
..Default::default()
}));
}
} else {
if let Some(scissors) = &self.builder_state.scissor_with_count {
if viewport_count != scissors.len() as u32 {
return Err(Box::new(ValidationError {
problem: "the currently bound graphics pipeline requires both \
the `DynamicState::ViewportWithCount` and the \
`DynamicState::ScissorWithCount` dynamic states, but \
the dynamic scissor count is not equal to the \
dynamic scissor count "
.into(),
vuids: vuids!(vuid_type, "viewportCount-03419"),
..Default::default()
}));
}
} else {
return Err(Box::new(ValidationError {
problem: format!(
"the currently bound graphics pipeline requires the \
`DynamicState::{:?}` dynamic state, but \
this state was either not set, or it was overwritten by a \
more recent `bind_pipeline_graphics` command",
dynamic_state
).into(),
vuids: vuids!(vuid_type, "scissorCount-03418", "viewportCount-03419"),
..Default::default()
}));
}
}
// TODO: VUID-vkCmdDrawIndexed-primitiveFragmentShadingRateWithMultipleViewports-04552
@ -2188,38 +2261,6 @@ where
// command buffer prior to this drawing command, and the viewportCount parameter of
// vkCmdSetViewportWithCountEXT must be 1
}
DynamicState::ViewportWScaling => todo!(),
DynamicState::TessellationDomainOrigin => todo!(),
DynamicState::DepthClampEnable => todo!(),
DynamicState::PolygonMode => todo!(),
DynamicState::RasterizationSamples => todo!(),
DynamicState::SampleMask => todo!(),
DynamicState::AlphaToCoverageEnable => todo!(),
DynamicState::AlphaToOneEnable => todo!(),
DynamicState::LogicOpEnable => todo!(),
DynamicState::ColorBlendEnable => todo!(),
DynamicState::ColorBlendEquation => todo!(),
DynamicState::ColorWriteMask => todo!(),
DynamicState::RasterizationStream => todo!(),
DynamicState::ConservativeRasterizationMode => todo!(),
DynamicState::ExtraPrimitiveOverestimationSize => todo!(),
DynamicState::DepthClipEnable => todo!(),
DynamicState::SampleLocationsEnable => todo!(),
DynamicState::ColorBlendAdvanced => todo!(),
DynamicState::ProvokingVertexMode => todo!(),
DynamicState::LineRasterizationMode => todo!(),
DynamicState::LineStippleEnable => todo!(),
DynamicState::DepthClipNegativeOneToOne => todo!(),
DynamicState::ViewportWScalingEnable => todo!(),
DynamicState::ViewportSwizzle => todo!(),
DynamicState::CoverageToColorEnable => todo!(),
DynamicState::CoverageToColorLocation => todo!(),
DynamicState::CoverageModulationMode => todo!(),
DynamicState::CoverageModulationTableEnable => todo!(),
DynamicState::CoverageModulationTable => todo!(),
DynamicState::ShadingRateImageEnable => todo!(),
DynamicState::RepresentativeFragmentTestEnable => todo!(),
DynamicState::CoverageReductionMode => todo!(),
}
}

View File

@ -108,7 +108,7 @@ impl Format {
/// Retrieves the properties of a format when used by a certain device.
#[deprecated(
since = "0.28.0",
note = "Use PhysicalDevice::format_properties instead"
note = "use PhysicalDevice::format_properties instead"
)]
#[inline]
pub fn properties(self, physical_device: PhysicalDevice) -> FormatProperties {

View File

@ -35,7 +35,7 @@ macro_rules! vulkan_bitflags {
Self(0)
}
#[deprecated(since = "0.31.0", note = "Use `empty` instead.")]
#[deprecated(since = "0.31.0", note = "use `empty` instead")]
#[doc = concat!("Returns a `", stringify!($ty), "` with none of the flags set.")]
#[inline]
pub const fn none() -> Self {
@ -263,7 +263,7 @@ macro_rules! vulkan_bitflags {
Self(0)
}
#[deprecated(since = "0.31.0", note = "Use `empty` instead.")]
#[deprecated(since = "0.31.0", note = "use `empty` instead")]
#[doc = concat!("Returns a `", stringify!($ty), "` with none of the flags set.")]
#[inline]
pub const fn none() -> Self {

View File

@ -24,9 +24,9 @@
use crate::{
device::Device,
macros::{vulkan_bitflags, vulkan_enum},
pipeline::StateMode,
Requires, RequiresAllOf, RequiresOneOf, ValidationError,
};
use std::iter;
/// Describes how the color output of the fragment shader is written to the attachment. See the
/// documentation of the `blend` module for more info.
@ -41,62 +41,84 @@ pub struct ColorBlendState {
/// fragment in the framebuffer attachment.
///
/// If set to `Some`, the [`logic_op`](crate::device::Features::logic_op) feature must be
/// enabled on the device. If set to `Some(Dynamic)`, then the
/// [`extended_dynamic_state2_logic_op`](crate::device::Features::extended_dynamic_state2_logic_op)
/// feature must also be enabled on the device.
pub logic_op: Option<StateMode<LogicOp>>,
/// enabled on the device.
///
/// The default value is `None`.
pub logic_op: Option<LogicOp>,
/// Sets the blend and output state for each color attachment. The number of elements must match
/// the number of color attachments in the framebuffer.
/// the number of color attachments in the subpass.
///
/// If there are multiple elements, and the `blend` and `color_write_mask` members of each
/// element differ, then the [`independent_blend`](crate::device::Features::independent_blend)
/// feature must be enabled on the device.
///
/// The default value is empty,
/// which must be overridden if the subpass has color attachments.
pub attachments: Vec<ColorBlendAttachmentState>,
/// The constant color to use for some of the `BlendFactor` variants.
pub blend_constants: StateMode<[f32; 4]>,
///
/// The default value is `[0.0; 4]`.
pub blend_constants: [f32; 4],
pub _ne: crate::NonExhaustive,
}
impl Default for ColorBlendState {
/// Returns [`ColorBlendState::new(1)`].
#[inline]
fn default() -> Self {
Self {
flags: ColorBlendStateFlags::empty(),
logic_op: None,
attachments: Vec::new(),
blend_constants: [0.0; 4],
_ne: crate::NonExhaustive(()),
}
}
}
impl ColorBlendState {
/// Returns a default `ColorBlendState` with `count` duplicates of `attachment_state`.
#[inline]
pub fn with_attachment_states(count: u32, attachment_state: ColorBlendAttachmentState) -> Self {
Self {
attachments: iter::repeat(attachment_state)
.take(count as usize)
.collect(),
..Default::default()
}
}
/// Creates a `ColorBlendState` with logical operations disabled, blend constants set to zero,
/// and `num` attachment entries that have blending disabled, and color write and all color
/// components enabled.
#[inline]
#[deprecated(since = "0.34.0")]
pub fn new(num: u32) -> Self {
Self {
flags: ColorBlendStateFlags::empty(),
logic_op: None,
attachments: (0..num)
.map(|_| ColorBlendAttachmentState {
blend: None,
color_write_mask: ColorComponents::all(),
color_write_enable: StateMode::Fixed(true),
})
.map(|_| ColorBlendAttachmentState::default())
.collect(),
blend_constants: StateMode::Fixed([0.0, 0.0, 0.0, 0.0]),
blend_constants: [0.0; 4],
_ne: crate::NonExhaustive(()),
}
}
/// Enables logical operations with the given logical operation.
#[inline]
#[deprecated(since = "0.34.0")]
pub fn logic_op(mut self, logic_op: LogicOp) -> Self {
self.logic_op = Some(StateMode::Fixed(logic_op));
self
}
/// Enables logical operations with a dynamic logical operation.
#[inline]
pub fn logic_op_dynamic(mut self) -> Self {
self.logic_op = Some(StateMode::Dynamic);
self.logic_op = Some(logic_op);
self
}
/// Enables blending for all attachments, with the given parameters.
#[inline]
#[deprecated(since = "0.34.0")]
pub fn blend(mut self, blend: AttachmentBlend) -> Self {
self.attachments
.iter_mut()
@ -106,6 +128,7 @@ impl ColorBlendState {
/// Enables blending for all attachments, with alpha blending.
#[inline]
#[deprecated(since = "0.34.0")]
pub fn blend_alpha(mut self) -> Self {
self.attachments
.iter_mut()
@ -115,6 +138,7 @@ impl ColorBlendState {
/// Enables blending for all attachments, with additive blending.
#[inline]
#[deprecated(since = "0.34.0")]
pub fn blend_additive(mut self) -> Self {
self.attachments.iter_mut().for_each(|attachment_state| {
attachment_state.blend = Some(AttachmentBlend::additive())
@ -124,6 +148,7 @@ impl ColorBlendState {
/// Sets the color write mask for all attachments.
#[inline]
#[deprecated(since = "0.34.0")]
pub fn color_write_mask(mut self, color_write_mask: ColorComponents) -> Self {
self.attachments
.iter_mut()
@ -133,15 +158,9 @@ impl ColorBlendState {
/// Sets the blend constants.
#[inline]
#[deprecated(since = "0.34.0")]
pub fn blend_constants(mut self, constants: [f32; 4]) -> Self {
self.blend_constants = StateMode::Fixed(constants);
self
}
/// Sets the blend constants as dynamic.
#[inline]
pub fn blend_constants_dynamic(mut self) -> Self {
self.blend_constants = StateMode::Dynamic;
self.blend_constants = constants;
self
}
@ -171,25 +190,10 @@ impl ColorBlendState {
}));
}
match logic_op {
StateMode::Fixed(logic_op) => logic_op.validate_device(device).map_err(|err| {
err.add_context("logic_op").set_vuids(&[
"VUID-VkPipelineColorBlendStateCreateInfo-logicOpEnable-00607",
])
})?,
StateMode::Dynamic => {
if !device.enabled_features().extended_dynamic_state2_logic_op {
return Err(Box::new(ValidationError {
context: "logic_op".into(),
problem: "is dynamic".into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
"extended_dynamic_state2_logic_op",
)])]),
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-04869"],
}));
}
}
}
logic_op.validate_device(device).map_err(|err| {
err.add_context("logic_op")
.set_vuids(&["VUID-VkPipelineColorBlendStateCreateInfo-logicOpEnable-00607"])
})?;
}
if device.enabled_features().independent_blend {
@ -225,14 +229,6 @@ impl ColorBlendState {
}
}
impl Default for ColorBlendState {
/// Returns [`ColorBlendState::new(1)`].
#[inline]
fn default() -> Self {
Self::new(1)
}
}
vulkan_bitflags! {
#[non_exhaustive]
@ -323,9 +319,13 @@ pub struct ColorBlendAttachmentState {
/// The blend parameters for the attachment.
///
/// If set to `None`, blending is disabled, and all incoming pixels will be used directly.
///
/// The default value is `None`.
pub blend: Option<AttachmentBlend>,
/// Sets which components of the final pixel value are written to the attachment.
///
/// The default value is `ColorComponents::all()`.
pub color_write_mask: ColorComponents,
/// Sets whether anything at all is written to the attachment. If enabled, the pixel data
@ -335,7 +335,20 @@ pub struct ColorBlendAttachmentState {
/// If set to anything other than `Fixed(true)`, the
/// [`color_write_enable`](crate::device::Features::color_write_enable) feature must be enabled
/// on the device.
pub color_write_enable: StateMode<bool>,
///
/// The default value is `true`.
pub color_write_enable: bool,
}
impl Default for ColorBlendAttachmentState {
#[inline]
fn default() -> Self {
Self {
blend: None,
color_write_mask: ColorComponents::all(),
color_write_enable: true,
}
}
}
impl ColorBlendAttachmentState {
@ -352,31 +365,15 @@ impl ColorBlendAttachmentState {
.map_err(|err| err.add_context("blend"))?;
}
match color_write_enable {
StateMode::Fixed(enable) => {
if !enable && !device.enabled_features().color_write_enable {
return Err(Box::new(ValidationError {
context: "color_write_enable".into(),
problem: "is `false`".into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
"color_write_enable",
)])]),
vuids: &["VUID-VkPipelineColorWriteCreateInfoEXT-pAttachments-04801"],
}));
}
}
StateMode::Dynamic => {
if !device.enabled_features().color_write_enable {
return Err(Box::new(ValidationError {
context: "color_write_enable".into(),
problem: "is dynamic".into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
"color_write_enable",
)])]),
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-04800"],
}));
}
}
if !color_write_enable && !device.enabled_features().color_write_enable {
return Err(Box::new(ValidationError {
context: "color_write_enable".into(),
problem: "is `false`".into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
"color_write_enable",
)])]),
vuids: &["VUID-VkPipelineColorWriteCreateInfoEXT-pAttachments-04801"],
}));
}
Ok(())
@ -387,26 +384,52 @@ impl ColorBlendAttachmentState {
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct AttachmentBlend {
/// The operation to apply to the source color component before applying `color_op`.
///
/// The default value is [`BlendFactor::SrcColor`].
pub src_color_blend_factor: BlendFactor,
/// The operation to apply to the destination color component before applying `color_op`.
///
/// The default value is [`BlendFactor::Zero`].
pub dst_color_blend_factor: BlendFactor,
/// The operation to apply between the color components of the source and destination pixels,
/// to produce the final pixel value.
///
/// The default value is [`BlendOp::Add`].
pub color_blend_op: BlendOp,
/// The operation to apply to the source alpha component before applying `alpha_op`.
///
/// The default value is [`BlendFactor::SrcColor`].
pub src_alpha_blend_factor: BlendFactor,
/// The operation to apply to the destination alpha component before applying `alpha_op`.
///
/// The default value is [`BlendFactor::Zero`].
pub dst_alpha_blend_factor: BlendFactor,
/// The operation to apply between the alpha component of the source and destination pixels,
/// to produce the final pixel value.
///
/// The default value is [`BlendOp::Add`].
pub alpha_blend_op: BlendOp,
}
impl Default for AttachmentBlend {
#[inline]
fn default() -> Self {
Self {
src_color_blend_factor: BlendFactor::SrcColor,
dst_color_blend_factor: BlendFactor::Zero,
color_blend_op: BlendOp::Add,
src_alpha_blend_factor: BlendFactor::SrcColor,
dst_alpha_blend_factor: BlendFactor::Zero,
alpha_blend_op: BlendOp::Add,
}
}
}
impl AttachmentBlend {
/// Builds an `AttachmentBlend` where the output of the fragment shader is ignored and the
/// destination is untouched.

View File

@ -23,8 +23,7 @@
use crate::{
device::Device,
macros::{vulkan_bitflags, vulkan_enum},
pipeline::StateMode,
Requires, RequiresAllOf, RequiresOneOf, ValidationError, Version,
Requires, RequiresAllOf, RequiresOneOf, ValidationError,
};
use std::ops::RangeInclusive;
@ -41,26 +40,32 @@ pub struct DepthStencilState {
///
/// If set to `None`, the depth test is disabled, all fragments will pass and no depth writes
/// are performed.
///
/// The default value is `None`.
pub depth: Option<DepthState>,
/// The state of the depth bounds test.
/// The minimum and maximum depth values to use for the depth bounds test.
/// Fragments with values outside this range are discarded.
///
/// If set to `None`, the depth bounds test is disabled, all fragments will pass.
pub depth_bounds: Option<DepthBoundsState>,
///
/// The default value is `None`.
pub depth_bounds: Option<RangeInclusive<f32>>,
/// The state of the stencil test.
///
/// If set to `None`, the stencil test is disabled, all fragments will pass and no stencil
/// writes are performed.
///
/// The default value is `None`.
pub stencil: Option<StencilState>,
pub _ne: crate::NonExhaustive,
}
impl DepthStencilState {
/// Creates a `DepthStencilState` where all tests are disabled and have no effect.
impl Default for DepthStencilState {
#[inline]
pub fn disabled() -> Self {
fn default() -> Self {
Self {
flags: DepthStencilStateFlags::empty(),
depth: Default::default(),
@ -69,18 +74,24 @@ impl DepthStencilState {
_ne: crate::NonExhaustive(()),
}
}
}
impl DepthStencilState {
/// Creates a `DepthStencilState` where all tests are disabled and have no effect.
#[inline]
#[deprecated(since = "0.34.0", note = "use `DepthStencilState::default` instead")]
pub fn disabled() -> Self {
Self::default()
}
/// Creates a `DepthStencilState` with a `Less` depth test, `depth_write` set to true, and other
/// tests disabled.
#[inline]
#[deprecated(since = "0.34.0", note = "use `DepthState::simple` instead")]
pub fn simple_depth_test() -> Self {
Self {
flags: DepthStencilStateFlags::empty(),
depth: Some(DepthState {
enable_dynamic: false,
compare_op: StateMode::Fixed(CompareOp::Less),
write_enable: StateMode::Fixed(true),
}),
depth: Some(DepthState::simple()),
depth_bounds: Default::default(),
stencil: Default::default(),
_ne: crate::NonExhaustive(()),
@ -107,7 +118,7 @@ impl DepthStencilState {
.map_err(|err| err.add_context("depth"))?;
}
if let Some(depth_bounds_state) = depth_bounds {
if let Some(depth_bounds) = depth_bounds {
if !device.enabled_features().depth_bounds {
return Err(Box::new(ValidationError {
context: "depth_bounds".into(),
@ -121,9 +132,29 @@ impl DepthStencilState {
}));
}
depth_bounds_state
.validate(device)
.map_err(|err| err.add_context("depth_bounds"))?;
if !device.enabled_extensions().ext_depth_range_unrestricted {
if !(0.0..1.0).contains(depth_bounds.start()) {
return Err(Box::new(ValidationError {
context: "depth_bounds.start".into(),
problem: "is not between 0.0 and 1.0 inclusive".into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
Requires::DeviceExtension("ext_depth_range_unrestricted"),
])]),
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-02510"],
}));
}
if !(0.0..1.0).contains(depth_bounds.end()) {
return Err(Box::new(ValidationError {
context: "depth_bounds.end".into(),
problem: "is not between 0.0 and 1.0 inclusive".into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
Requires::DeviceExtension("ext_depth_range_unrestricted"),
])]),
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-02510"],
}));
}
}
}
if let Some(stencil_state) = stencil {
@ -136,14 +167,6 @@ impl DepthStencilState {
}
}
impl Default for DepthStencilState {
/// Returns [`DepthStencilState::disabled()`].
#[inline]
fn default() -> Self {
DepthStencilState::disabled()
}
}
vulkan_bitflags! {
#[non_exhaustive]
@ -170,322 +193,93 @@ vulkan_bitflags! {
/// The state in a graphics pipeline describing how the depth test should behave when enabled.
#[derive(Clone, Copy, Debug)]
pub struct DepthState {
/// Sets whether depth testing should be enabled and disabled dynamically. If set to `false`,
/// depth testing is always enabled.
///
/// If set to `true`, the device API version must be at least 1.3, or the
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature must be
/// enabled on the device.
pub enable_dynamic: bool,
/// Sets whether the value in the depth buffer will be updated when the depth test succeeds.
///
/// If set to `Dynamic`, the device API version must be at least 1.3, or the
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature must be
/// enabled on the device.
pub write_enable: StateMode<bool>,
/// The default value is `false`.
pub write_enable: bool,
/// Comparison operation to use between the depth value of each incoming fragment and the depth
/// value currently in the depth buffer.
///
/// If set to `Dynamic`, the device API version must be at least 1.3, or the
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature must be
/// enabled on the device.
pub compare_op: StateMode<CompareOp>,
}
impl DepthState {
pub(crate) fn validate(self, device: &Device) -> Result<(), Box<ValidationError>> {
let Self {
enable_dynamic,
write_enable,
compare_op,
} = self;
if enable_dynamic
&& !(device.api_version() >= Version::V1_3
|| device.enabled_features().extended_dynamic_state)
{
return Err(Box::new(ValidationError {
context: "enable_dynamic".into(),
problem: "is `true`".into(),
requires_one_of: RequiresOneOf(&[
RequiresAllOf(&[Requires::APIVersion(Version::V1_3)]),
RequiresAllOf(&[Requires::Feature("extended_dynamic_state")]),
]),
// vuids?
..Default::default()
}));
}
match write_enable {
StateMode::Fixed(_) => (),
StateMode::Dynamic => {
if !(device.api_version() >= Version::V1_3
|| device.enabled_features().extended_dynamic_state)
{
return Err(Box::new(ValidationError {
context: "write_enable".into(),
problem: "is dynamic".into(),
requires_one_of: RequiresOneOf(&[
RequiresAllOf(&[Requires::APIVersion(Version::V1_3)]),
RequiresAllOf(&[Requires::Feature("extended_dynamic_state")]),
]),
// vuids?
..Default::default()
}));
}
}
}
match compare_op {
StateMode::Fixed(compare_op) => {
compare_op.validate_device(device).map_err(|err| {
err.add_context("compare_op").set_vuids(&[
"VUID-VkPipelineDepthStencilStateCreateInfo-depthCompareOp-parameter",
])
})?;
}
StateMode::Dynamic => {
if !(device.api_version() >= Version::V1_3
|| device.enabled_features().extended_dynamic_state)
{
return Err(Box::new(ValidationError {
context: "compare_op".into(),
problem: "is dynamic".into(),
requires_one_of: RequiresOneOf(&[
RequiresAllOf(&[Requires::APIVersion(Version::V1_3)]),
RequiresAllOf(&[Requires::Feature("extended_dynamic_state")]),
]),
// vuids?
..Default::default()
}));
}
}
}
Ok(())
}
/// The default value is [`CompareOp::Always`].
pub compare_op: CompareOp,
}
impl Default for DepthState {
/// Creates a `DepthState` with no dynamic state, depth writes disabled and `compare_op` set
/// to always pass.
#[inline]
fn default() -> Self {
Self {
enable_dynamic: false,
write_enable: StateMode::Fixed(false),
compare_op: StateMode::Fixed(CompareOp::Always),
write_enable: false,
compare_op: CompareOp::Always,
}
}
}
/// The state in a graphics pipeline describing how the depth bounds test should behave when
/// enabled.
#[derive(Clone, Debug)]
pub struct DepthBoundsState {
/// Sets whether depth bounds testing should be enabled and disabled dynamically. If set to
/// `false`, depth bounds testing is always enabled.
///
/// If set to `true`, the device API version must be at least 1.3, or the
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature must be
/// enabled on the device.
pub enable_dynamic: bool,
impl DepthState {
/// Returns a `DepthState` with a `Less` depth test and depth writes enabled.
#[inline]
pub fn simple() -> Self {
Self {
compare_op: CompareOp::Less,
write_enable: true,
}
}
/// The minimum and maximum depth values to use for the test. Fragments with values outside this
/// range are discarded.
///
/// If set to `Dynamic`, the device API version must be at least 1.3, or the
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature must be
/// enabled on the device.
pub bounds: StateMode<RangeInclusive<f32>>,
}
impl DepthBoundsState {
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
let &Self {
enable_dynamic,
ref bounds,
pub(crate) fn validate(self, device: &Device) -> Result<(), Box<ValidationError>> {
let Self {
write_enable: _,
compare_op,
} = self;
if enable_dynamic
&& !(device.api_version() >= Version::V1_3
|| device.enabled_features().extended_dynamic_state)
{
return Err(Box::new(ValidationError {
context: "enable_dynamic".into(),
problem: "is `true`".into(),
requires_one_of: RequiresOneOf(&[
RequiresAllOf(&[Requires::APIVersion(Version::V1_3)]),
RequiresAllOf(&[Requires::Feature("extended_dynamic_state")]),
]),
// vuids?
..Default::default()
}));
}
if let StateMode::Fixed(bounds) = bounds {
if !device.enabled_extensions().ext_depth_range_unrestricted {
if !(0.0..1.0).contains(bounds.start()) {
return Err(Box::new(ValidationError {
context: "bounds.start".into(),
problem: "is not between 0.0 and 1.0 inclusive".into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
Requires::DeviceExtension("ext_depth_range_unrestricted"),
])]),
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-02510"],
}));
}
if !(0.0..1.0).contains(bounds.end()) {
return Err(Box::new(ValidationError {
context: "bounds.end".into(),
problem: "is not between 0.0 and 1.0 inclusive".into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
Requires::DeviceExtension("ext_depth_range_unrestricted"),
])]),
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-02510"],
}));
}
}
}
compare_op.validate_device(device).map_err(|err| {
err.add_context("compare_op")
.set_vuids(&["VUID-VkPipelineDepthStencilStateCreateInfo-depthCompareOp-parameter"])
})?;
Ok(())
}
}
impl Default for DepthBoundsState {
/// Creates a `DepthBoundsState` with no dynamic state and the bounds set to `0.0..=1.0`.
#[inline]
fn default() -> Self {
Self {
enable_dynamic: false,
bounds: StateMode::Fixed(0.0..=1.0),
}
}
}
/// The state in a graphics pipeline describing how the stencil test should behave when enabled.
///
/// Dynamic state can only be enabled or disabled for both faces at once. Therefore, the dynamic
/// state values in `StencilOpState`, must match: the values for `front` and `back` must either both
/// be `Fixed` or both be `Dynamic`.
#[derive(Clone, Debug)]
pub struct StencilState {
/// Sets whether stencil testing should be enabled and disabled dynamically. If set to
/// `false`, stencil testing is always enabled.
///
/// If set to `true`, the device API version must be at least 1.3, or the
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature must be
/// enabled on the device.
pub enable_dynamic: bool,
/// The stencil operation state to use for points and lines, and for triangles whose front is
/// facing the user.
///
/// The default value is `StencilOpState::default()`.
pub front: StencilOpState,
/// The stencil operation state to use for triangles whose back is facing the user.
///
/// The default value is `StencilOpState::default()`.
pub back: StencilOpState,
}
impl Default for StencilState {
#[inline]
fn default() -> Self {
Self {
front: Default::default(),
back: Default::default(),
}
}
}
impl StencilState {
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
let &StencilState {
enable_dynamic,
ref front,
ref back,
} = self;
if enable_dynamic
&& !(device.api_version() >= Version::V1_3
|| device.enabled_features().extended_dynamic_state)
{
return Err(Box::new(ValidationError {
context: "enable_dynamic".into(),
problem: "is `true`".into(),
requires_one_of: RequiresOneOf(&[
RequiresAllOf(&[Requires::APIVersion(Version::V1_3)]),
RequiresAllOf(&[Requires::Feature("extended_dynamic_state")]),
]),
// vuids?
..Default::default()
}));
}
front
.ops
.validate(device)
.map_err(|err| err.add_context("front.ops"))?;
match (front.ops, back.ops) {
(StateMode::Fixed(front_ops), StateMode::Fixed(back_ops)) => {
front_ops
.validate(device)
.map_err(|err| err.add_context("front.ops"))?;
back_ops
.validate(device)
.map_err(|err| err.add_context("back.ops"))?;
}
(StateMode::Dynamic, StateMode::Dynamic) => {
if !(device.api_version() >= Version::V1_3
|| device.enabled_features().extended_dynamic_state)
{
return Err(Box::new(ValidationError {
problem: "`front.ops` and `back.ops` are dynamic".into(),
requires_one_of: RequiresOneOf(&[
RequiresAllOf(&[Requires::APIVersion(Version::V1_3)]),
RequiresAllOf(&[Requires::Feature("extended_dynamic_state")]),
]),
// vuids?
..Default::default()
}));
}
}
_ => {
return Err(Box::new(ValidationError {
problem: "`front.ops` and `back.ops` are \
not both fixed or both dynamic"
.into(),
// vuids?
..Default::default()
}));
}
}
if !matches!(
(front.compare_mask, back.compare_mask),
(StateMode::Fixed(_), StateMode::Fixed(_)) | (StateMode::Dynamic, StateMode::Dynamic)
) {
return Err(Box::new(ValidationError {
problem: "`front.compare_mask` and `back.compare_mask` are \
not both fixed or both dynamic"
.into(),
// vuids?
..Default::default()
}));
}
if !matches!(
(front.write_mask, back.write_mask),
(StateMode::Fixed(_), StateMode::Fixed(_)) | (StateMode::Dynamic, StateMode::Dynamic)
) {
return Err(Box::new(ValidationError {
problem: "`front.write_mask` and `back.write_mask` are \
not both fixed or both dynamic"
.into(),
// vuids?
..Default::default()
}));
}
if !matches!(
(front.reference, back.reference),
(StateMode::Fixed(_), StateMode::Fixed(_)) | (StateMode::Dynamic, StateMode::Dynamic)
) {
return Err(Box::new(ValidationError {
problem: "`front.reference` and `back.reference` are \
not both fixed or both dynamic"
.into(),
// vuids?
..Default::default()
}));
}
back.ops
.validate(device)
.map_err(|err| err.add_context("back.ops"))?;
Ok(())
}
@ -496,19 +290,21 @@ impl StencilState {
pub struct StencilOpState {
/// The stencil operations to perform.
///
/// If set to `Dynamic`, the device API version must be at least 1.3, or the
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature must be
/// enabled on the device.
pub ops: StateMode<StencilOps>,
/// The default value is `StencilOps::default()`.
pub ops: StencilOps,
/// A bitmask that selects the bits of the unsigned integer stencil values participating in the
/// stencil test. Ignored if `compare_op` is `Never` or `Always`.
pub compare_mask: StateMode<u32>,
///
/// The default value is [`u32::MAX`].
pub compare_mask: u32,
/// A bitmask that selects the bits of the unsigned integer stencil values updated by the
/// stencil test in the stencil framebuffer attachment. Ignored if the relevant operation is
/// `Keep`.
pub write_mask: StateMode<u32>,
///
/// The default value is [`u32::MAX`].
pub write_mask: u32,
/// Reference value that is used in the unsigned stencil comparison. The stencil test is
/// considered to pass if the `compare_op` between the stencil buffer value and this reference
@ -519,19 +315,19 @@ pub struct StencilOpState {
/// are not equal, then the
/// [`separate_stencil_mask_ref`](crate::device::Features::separate_stencil_mask_ref)
/// feature must be enabled on the device.
pub reference: StateMode<u32>,
///
/// The default value is [`u32::MAX`].
pub reference: u32,
}
impl Default for StencilOpState {
/// Creates a `StencilOpState` with no dynamic state, `compare_op` set to `Never`, the stencil
/// operations set to `Keep`, and the masks and reference values set to `u32::MAX`.
#[inline]
fn default() -> StencilOpState {
StencilOpState {
ops: StateMode::Fixed(Default::default()),
compare_mask: StateMode::Fixed(u32::MAX),
write_mask: StateMode::Fixed(u32::MAX),
reference: StateMode::Fixed(u32::MAX),
ops: Default::default(),
compare_mask: u32::MAX,
write_mask: u32::MAX,
reference: u32::MAX,
}
}
}
@ -539,19 +335,39 @@ impl Default for StencilOpState {
#[derive(Clone, Copy, Debug)]
pub struct StencilOps {
/// The operation to perform when the stencil test failed.
///
/// The default value is [`StencilOp::Keep`].
pub fail_op: StencilOp,
/// The operation to perform when both the depth test and the stencil test passed.
///
/// The default value is [`StencilOp::Keep`].
pub pass_op: StencilOp,
/// The operation to perform when the stencil test passed but the depth test failed.
///
/// The default value is [`StencilOp::Keep`].
pub depth_fail_op: StencilOp,
/// The comparison to perform between the existing stencil value in the stencil buffer, and
/// the reference value (given by `reference`).
///
/// The default value is [`CompareOp::Never`].
pub compare_op: CompareOp,
}
impl Default for StencilOps {
#[inline]
fn default() -> Self {
Self {
pass_op: StencilOp::Keep,
fail_op: StencilOp::Keep,
depth_fail_op: StencilOp::Keep,
compare_op: CompareOp::Never,
}
}
}
impl StencilOps {
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
let &Self {
@ -585,20 +401,6 @@ impl StencilOps {
}
}
impl Default for StencilOps {
/// Creates a `StencilOps` with no dynamic state, `compare_op` set to `Never` and the stencil
/// operations set to `Keep`.
#[inline]
fn default() -> Self {
Self {
pass_op: StencilOp::Keep,
fail_op: StencilOp::Keep,
depth_fail_op: StencilOp::Keep,
compare_op: CompareOp::Never,
}
}
}
vulkan_enum! {
#[non_exhaustive]

View File

@ -12,38 +12,55 @@
//! The discard rectangle test is similar to, but separate from the scissor test.
use crate::{
device::Device,
macros::vulkan_enum,
pipeline::{graphics::viewport::Scissor, PartialStateMode},
ValidationError,
device::Device, macros::vulkan_enum, pipeline::graphics::viewport::Scissor, ValidationError,
};
/// The state in a graphics pipeline describing how the discard rectangle test should behave.
#[derive(Clone, Debug)]
pub struct DiscardRectangleState {
/// Sets whether the discard rectangle test operates inclusively or exclusively.
///
/// The default value is [`DiscardRectangleMode::Exclusive`].
pub mode: DiscardRectangleMode,
/// Specifies the discard rectangles. If set to `Dynamic`, it specifies only the number of
/// rectangles used from the dynamic state.
/// Specifies the discard rectangles.
///
/// If set to `Dynamic` or to `Fixed` with a non-empty list, the
/// When [`DynamicState::DiscardRectangle`] is used, the values of each rectangle are ignored
/// and must be set dynamically, but the number of discard rectangles is fixed and
/// must be matched when setting the dynamic value.
///
/// If this not not empty, then the
/// [`ext_discard_rectangles`](crate::device::DeviceExtensions::ext_discard_rectangles)
/// extension must be enabled on the device.
pub rectangles: PartialStateMode<Vec<Scissor>, u32>,
///
/// The default value is empty.
///
/// [`DynamicState::DiscardRectangle`]: crate::pipeline::DynamicState::DiscardRectangle
pub rectangles: Vec<Scissor>,
pub _ne: crate::NonExhaustive,
}
impl Default for DiscardRectangleState {
#[inline]
fn default() -> Self {
Self {
mode: DiscardRectangleMode::Exclusive,
rectangles: Vec::new(),
_ne: crate::NonExhaustive(()),
}
}
}
impl DiscardRectangleState {
/// Creates a `DiscardRectangleState` in exclusive mode with zero rectangles.
#[inline]
#[deprecated(
since = "0.34.0",
note = "use `DiscardRectangleState::default` instead"
)]
pub fn new() -> Self {
Self {
mode: DiscardRectangleMode::Exclusive,
rectangles: PartialStateMode::Fixed(Vec::new()),
_ne: crate::NonExhaustive(()),
}
Self::default()
}
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
@ -61,12 +78,7 @@ impl DiscardRectangleState {
])
})?;
let discard_rectangle_count = match rectangles {
PartialStateMode::Dynamic(count) => *count,
PartialStateMode::Fixed(rectangles) => rectangles.len() as u32,
};
if discard_rectangle_count > properties.max_discard_rectangles.unwrap() {
if rectangles.len() as u32 > properties.max_discard_rectangles.unwrap() {
return Err(Box::new(ValidationError {
context: "rectangles".into(),
problem: "the length exceeds the `max_discard_rectangles` limit".into(),
@ -81,14 +93,6 @@ impl DiscardRectangleState {
}
}
impl Default for DiscardRectangleState {
/// Returns [`DiscardRectangleState::new`].
#[inline]
fn default() -> Self {
Self::new()
}
}
vulkan_enum! {
#[non_exhaustive]

View File

@ -10,10 +10,7 @@
//! Configures how input vertices are assembled into primitives.
use crate::{
device::Device,
macros::vulkan_enum,
pipeline::{PartialStateMode, StateMode},
Requires, RequiresAllOf, RequiresOneOf, ValidationError, Version,
device::Device, macros::vulkan_enum, Requires, RequiresAllOf, RequiresOneOf, ValidationError,
};
/// The state in a graphics pipeline describing how the input assembly stage should behave.
@ -21,12 +18,17 @@ use crate::{
pub struct InputAssemblyState {
/// The type of primitives.
///
/// Note that some topologies require a feature to be enabled on the device.
/// When [`DynamicState::PrimitiveTopology`] is used, if the
/// [`dynamic_primitive_topology_unrestricted`] device property is `false`, then
/// the dynamically set primitive topology must belong to the same *topology class* as
/// `topology`.
/// In practice, this is simply the first word in the name of the topology.
///
/// If set to `Dynamic`, the device API version must be at least 1.3, or the
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature must be
/// enabled on the device.
pub topology: PartialStateMode<PrimitiveTopology, PrimitiveTopologyClass>,
/// The default value is [`PrimitiveTopology::TriangleList`].
///
/// [`DynamicState::PrimitiveTopology`]: crate::pipeline::DynamicState::PrimitiveTopology
/// [`dynamic_primitive_topology_unrestricted`]: crate::device::Properties::dynamic_primitive_topology_unrestricted
pub topology: PrimitiveTopology,
/// If true, then when drawing with an index buffer, the special index value consisting of the
/// maximum unsigned value (`0xff`, `0xffff` or `0xffffffff`) will tell the GPU that it is the
@ -36,54 +38,54 @@ pub struct InputAssemblyState {
/// topologies require a feature to be enabled on the device when combined with primitive
/// restart.
///
/// If set to `Dynamic`, the device API version must be at least 1.3, or the
/// [`extended_dynamic_state2`](crate::device::Features::extended_dynamic_state2) feature must
/// be enabled on the device.
pub primitive_restart_enable: StateMode<bool>,
/// The default value is `false`.
pub primitive_restart_enable: bool,
pub _ne: crate::NonExhaustive,
}
impl Default for InputAssemblyState {
/// Returns [`InputAssemblyState::new()`].
#[inline]
fn default() -> Self {
Self {
topology: PrimitiveTopology::TriangleList,
primitive_restart_enable: false,
_ne: crate::NonExhaustive(()),
}
}
}
impl InputAssemblyState {
/// Creates an `InputAssemblyState` with the `TriangleList` topology and primitive restart
/// disabled.
#[inline]
#[deprecated(since = "0.34.0", note = "use `InputAssemblyState::default` instead")]
pub fn new() -> Self {
Self {
topology: PartialStateMode::Fixed(PrimitiveTopology::TriangleList),
primitive_restart_enable: StateMode::Fixed(false),
topology: PrimitiveTopology::TriangleList,
primitive_restart_enable: false,
_ne: crate::NonExhaustive(()),
}
}
/// Sets the primitive topology.
#[inline]
#[deprecated(since = "0.34.0")]
pub fn topology(mut self, topology: PrimitiveTopology) -> Self {
self.topology = PartialStateMode::Fixed(topology);
self
}
/// Sets the primitive topology to dynamic.
#[inline]
pub fn topology_dynamic(mut self, topology_class: PrimitiveTopologyClass) -> Self {
self.topology = PartialStateMode::Dynamic(topology_class);
self.topology = topology;
self
}
/// Enables primitive restart.
#[inline]
#[deprecated(since = "0.34.0")]
pub fn primitive_restart_enable(mut self) -> Self {
self.primitive_restart_enable = StateMode::Fixed(true);
self
}
/// Sets primitive restart enable to dynmamic.
#[inline]
pub fn primitive_restart_enable_dynamic(mut self) -> Self {
self.primitive_restart_enable = StateMode::Dynamic;
self.primitive_restart_enable = true;
self
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
let &Self {
topology,
@ -91,152 +93,96 @@ impl InputAssemblyState {
_ne: _,
} = self;
match topology {
PartialStateMode::Fixed(topology) => {
topology.validate_device(device).map_err(|err| {
err.add_context("topology").set_vuids(&[
"VUID-VkPipelineInputAssemblyStateCreateInfo-topology-parameter",
])
})?;
topology.validate_device(device).map_err(|err| {
err.add_context("topology")
.set_vuids(&["VUID-VkPipelineInputAssemblyStateCreateInfo-topology-parameter"])
})?;
match topology {
PrimitiveTopology::TriangleFan => {
if device.enabled_extensions().khr_portability_subset
&& !device.enabled_features().triangle_fans
{
return Err(Box::new(ValidationError {
problem: "this device is a portability subset device, and \
`topology` is `PrimitiveTopology::TriangleFan`"
.into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
Requires::Feature("triangle_fans"),
])]),
vuids: &["VUID-VkPipelineInputAssemblyStateCreateInfo-triangleFans-04452"],
..Default::default()
}));
}
}
PrimitiveTopology::LineListWithAdjacency
| PrimitiveTopology::LineStripWithAdjacency
| PrimitiveTopology::TriangleListWithAdjacency
| PrimitiveTopology::TriangleStripWithAdjacency => {
if !device.enabled_features().geometry_shader {
return Err(Box::new(ValidationError {
context: "topology".into(),
problem: "is `PrimitiveTopology::*WithAdjacency`".into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
Requires::Feature("geometry_shader"),
])]),
vuids: &[
"VUID-VkPipelineInputAssemblyStateCreateInfo-topology-00429",
],
}));
}
}
PrimitiveTopology::PatchList => {
if !device.enabled_features().tessellation_shader {
return Err(Box::new(ValidationError {
context: "topology".into(),
problem: "is `PrimitiveTopology::PatchList`".into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
Requires::Feature("tessellation_shader"),
])]),
vuids: &[
"VUID-VkPipelineInputAssemblyStateCreateInfo-topology-00430",
],
}));
}
}
_ => (),
match topology {
PrimitiveTopology::TriangleFan => {
if device.enabled_extensions().khr_portability_subset
&& !device.enabled_features().triangle_fans
{
return Err(Box::new(ValidationError {
problem: "this device is a portability subset device, and \
`topology` is `PrimitiveTopology::TriangleFan`"
.into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
"triangle_fans",
)])]),
vuids: &["VUID-VkPipelineInputAssemblyStateCreateInfo-triangleFans-04452"],
..Default::default()
}));
}
}
PartialStateMode::Dynamic(topology_class) => {
topology_class
.example()
.validate_device(device)
.map_err(|err| {
err.add_context("topology").set_vuids(&[
"VUID-VkPipelineInputAssemblyStateCreateInfo-topology-parameter",
])
})?;
if !(device.api_version() >= Version::V1_3
|| device.enabled_features().extended_dynamic_state)
{
PrimitiveTopology::LineListWithAdjacency
| PrimitiveTopology::LineStripWithAdjacency
| PrimitiveTopology::TriangleListWithAdjacency
| PrimitiveTopology::TriangleStripWithAdjacency => {
if !device.enabled_features().geometry_shader {
return Err(Box::new(ValidationError {
context: "topology".into(),
problem: "is dynamic".into(),
requires_one_of: RequiresOneOf(&[
RequiresAllOf(&[Requires::APIVersion(Version::V1_3)]),
RequiresAllOf(&[Requires::Feature("extended_dynamic_state")]),
]),
// vuids?
..Default::default()
problem: "is `PrimitiveTopology::*WithAdjacency`".into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
"geometry_shader",
)])]),
vuids: &["VUID-VkPipelineInputAssemblyStateCreateInfo-topology-00429"],
}));
}
}
PrimitiveTopology::PatchList => {
if !device.enabled_features().tessellation_shader {
return Err(Box::new(ValidationError {
context: "topology".into(),
problem: "is `PrimitiveTopology::PatchList`".into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
"tessellation_shader",
)])]),
vuids: &["VUID-VkPipelineInputAssemblyStateCreateInfo-topology-00430"],
}));
}
}
_ => (),
}
match primitive_restart_enable {
StateMode::Fixed(primitive_restart_enable) => {
if primitive_restart_enable {
match topology {
PartialStateMode::Fixed(
PrimitiveTopology::PointList
| PrimitiveTopology::LineList
| PrimitiveTopology::TriangleList
| PrimitiveTopology::LineListWithAdjacency
| PrimitiveTopology::TriangleListWithAdjacency,
) => {
if !device.enabled_features().primitive_topology_list_restart {
return Err(Box::new(ValidationError {
problem: "`topology` is `PrimitiveTopology::*List`, and \
`primitive_restart_enable` is `true`"
.into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
Requires::Feature("primitive_topology_list_restart"),
])]),
vuids: &["VUID-VkPipelineInputAssemblyStateCreateInfo-topology-06252"],
..Default::default()
}));
}
}
PartialStateMode::Fixed(PrimitiveTopology::PatchList) => {
if !device
.enabled_features()
.primitive_topology_patch_list_restart
{
return Err(Box::new(ValidationError {
problem: "`topology` is `PrimitiveTopology::PatchList`, and \
`primitive_restart_enable` is `true`"
.into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
Requires::Feature("primitive_topology_patch_list_restart"),
])]),
vuids: &["VUID-VkPipelineInputAssemblyStateCreateInfo-topology-06253"],
..Default::default()
}));
}
}
_ => (),
if primitive_restart_enable {
match topology {
PrimitiveTopology::PointList
| PrimitiveTopology::LineList
| PrimitiveTopology::TriangleList
| PrimitiveTopology::LineListWithAdjacency
| PrimitiveTopology::TriangleListWithAdjacency => {
if !device.enabled_features().primitive_topology_list_restart {
return Err(Box::new(ValidationError {
problem: "`topology` is `PrimitiveTopology::*List`, and \
`primitive_restart_enable` is `true`"
.into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
"primitive_topology_list_restart",
)])]),
vuids: &["VUID-VkPipelineInputAssemblyStateCreateInfo-topology-06252"],
..Default::default()
}));
}
}
}
StateMode::Dynamic => {
if !(device.api_version() >= Version::V1_3
|| device.enabled_features().extended_dynamic_state2)
{
return Err(Box::new(ValidationError {
context: "primitive_restart_enable".into(),
problem: "is dynamic".into(),
requires_one_of: RequiresOneOf(&[
RequiresAllOf(&[Requires::APIVersion(Version::V1_3)]),
RequiresAllOf(&[Requires::Feature("extended_dynamic_state")]),
]),
// vuids?
..Default::default()
}));
PrimitiveTopology::PatchList => {
if !device
.enabled_features()
.primitive_topology_patch_list_restart
{
return Err(Box::new(ValidationError {
problem: "`topology` is `PrimitiveTopology::PatchList`, and \
`primitive_restart_enable` is `true`"
.into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
"primitive_topology_patch_list_restart",
)])]),
vuids: &["VUID-VkPipelineInputAssemblyStateCreateInfo-topology-06253"],
..Default::default()
}));
}
}
_ => (),
}
}
@ -244,19 +190,17 @@ impl InputAssemblyState {
}
}
impl Default for InputAssemblyState {
/// Returns [`InputAssemblyState::new()`].
#[inline]
fn default() -> Self {
Self::new()
}
}
vulkan_enum! {
#[non_exhaustive]
/// Describes how vertices must be grouped together to form primitives.
///
/// When [`DynamicState::PrimitiveTopology`] is used, if the
/// [`dynamic_primitive_topology_unrestricted`] device property is `false`, then
/// the dynamically set primitive topology must belong to the same *topology class* as what
/// was set during pipeline creation.
/// In practice, this is simply the first word in the name of the topology.
///
/// When enabling primitive restart, "list" topologies require a feature to be enabled on the
/// device:
/// - The `PatchList` topology requires the
@ -265,40 +209,34 @@ vulkan_enum! {
/// - All other "list" topologies require the
/// [`primitive_topology_list_restart`](crate::device::Features::primitive_topology_list_restart)
/// feature.
PrimitiveTopology impl {
/// Returns the topology class of this topology.
#[inline]
pub fn class(self) -> PrimitiveTopologyClass {
match self {
Self::PointList => PrimitiveTopologyClass::Point,
Self::LineList
| Self::LineStrip
| Self::LineListWithAdjacency
| Self::LineStripWithAdjacency => PrimitiveTopologyClass::Line,
Self::TriangleList
| Self::TriangleStrip
| Self::TriangleFan
| Self::TriangleListWithAdjacency
| Self::TriangleStripWithAdjacency => PrimitiveTopologyClass::Triangle,
Self::PatchList => PrimitiveTopologyClass::Patch,
}
}
}
= PrimitiveTopology(i32);
///
/// [`DynamicState::PrimitiveTopology`]: crate::pipeline::DynamicState::PrimitiveTopology
/// [`dynamic_primitive_topology_unrestricted`]: crate::device::Properties::dynamic_primitive_topology_unrestricted
PrimitiveTopology = PrimitiveTopology(i32);
/// A series of separate point primitives.
///
/// Topology class: Point
PointList = POINT_LIST,
/// A series of separate line primitives.
///
/// Topology class: Line
LineList = LINE_LIST,
/// A series of consecutive line primitives, with consecutive lines sharing a vertex.
///
/// Topology class: Line
LineStrip = LINE_STRIP,
/// A series of separate triangle primitives.
///
/// Topology class: Triangle
TriangleList = TRIANGLE_LIST,
/// A series of consecutive triangle primitives, with consecutive triangles sharing an edge (two vertices).
///
/// Topology class: Triangle
TriangleStrip = TRIANGLE_STRIP,
/// A series of consecutive triangle primitives, with all triangles sharing a common vertex (the first).
@ -306,26 +244,38 @@ vulkan_enum! {
/// On [portability subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag)
/// devices, the [`triangle_fans`](crate::device::Features::triangle_fans)
/// feature must be enabled on the device.
///
/// Topology class: Triangle
TriangleFan = TRIANGLE_FAN,
/// As `LineList, but with adjacency, used in combination with geometry shaders. Requires the
/// [`geometry_shader`](crate::device::Features::geometry_shader) feature.
///
/// Topology class: Line
LineListWithAdjacency = LINE_LIST_WITH_ADJACENCY,
/// As `LineStrip`, but with adjacency, used in combination with geometry shaders. Requires the
/// [`geometry_shader`](crate::device::Features::geometry_shader) feature.
///
/// Topology class: Line
LineStripWithAdjacency = LINE_STRIP_WITH_ADJACENCY,
/// As `TriangleList`, but with adjacency, used in combination with geometry shaders. Requires
/// the [`geometry_shader`](crate::device::Features::geometry_shader) feature.
///
/// Topology class: Triangle
TriangleListWithAdjacency = TRIANGLE_LIST_WITH_ADJACENCY,
/// As `TriangleStrip`, but with adjacency, used in combination with geometry shaders. Requires
/// the [`geometry_shader`](crate::device::Features::geometry_shader) feature.
///
/// Topology class: Triangle
TriangleStripWithAdjacency = TRIANGLE_STRIP_WITH_ADJACENCY,
/// Separate patch primitives, used in combination with tessellation shaders. Requires the
/// [`tessellation_shader`](crate::device::Features::tessellation_shader) feature.
///
/// Topology class: Patch
PatchList = PATCH_LIST,
}
@ -338,24 +288,3 @@ impl Default for PrimitiveTopology {
PrimitiveTopology::TriangleList
}
}
/// Describes the shape of a primitive topology.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum PrimitiveTopologyClass {
Point,
Line,
Triangle,
Patch,
}
impl PrimitiveTopologyClass {
/// Returns a representative example of this topology class.
pub(crate) fn example(self) -> PrimitiveTopology {
match self {
Self::Point => PrimitiveTopology::PointList,
Self::Line => PrimitiveTopology::LineList,
Self::Triangle => PrimitiveTopology::TriangleList,
Self::Patch => PrimitiveTopology::PatchList,
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -36,12 +36,14 @@ pub struct MultisampleState {
///
/// If set to `Some`, the [`sample_rate_shading`](crate::device::Features::sample_rate_shading)
/// feature must be enabled on the device.
///
/// The default value is `None`.
pub sample_shading: Option<f32>,
/// A mask of bits that is ANDed with the coverage mask of each set of `rasterization_samples`
/// samples. Only the first `rasterization_samples / 32` bits are used, the rest is ignored.
///
/// The default value is `[0xFFFFFFFF; 2]`.
/// The default value is `[u32::MAX; 2]`.
pub sample_mask: [u32; 2], // 64 bits for needed for 64 SampleCount
/// Controls whether the alpha value of the fragment will be used in an implementation-defined
@ -49,6 +51,8 @@ pub struct MultisampleState {
/// then about half of the samples will be discarded. If you render to a multisample image, this
/// means that the color will end up being mixed with whatever color was underneath, which gives
/// the same effect as alpha blending.
///
/// The default value is `false`.
pub alpha_to_coverage_enable: bool,
/// Controls whether the alpha value of all the samples will be forced to 1.0 (or the
@ -56,24 +60,34 @@ pub struct MultisampleState {
///
/// If set to `true`, the [`alpha_to_one`](crate::device::Features::alpha_to_one)
/// feature must be enabled on the device.
///
/// The default value is `false`.
pub alpha_to_one_enable: bool,
pub _ne: crate::NonExhaustive,
}
impl MultisampleState {
/// Creates a `MultisampleState` with multisampling disabled.
impl Default for MultisampleState {
#[inline]
pub fn new() -> MultisampleState {
MultisampleState {
fn default() -> Self {
Self {
rasterization_samples: SampleCount::Sample1,
sample_shading: None,
sample_mask: [0xFFFFFFFF; 2],
sample_mask: [u32::MAX; 2],
alpha_to_coverage_enable: false,
alpha_to_one_enable: false,
_ne: crate::NonExhaustive(()),
}
}
}
impl MultisampleState {
/// Creates a `MultisampleState` with multisampling disabled.
#[inline]
#[deprecated(since = "0.34.0", note = "use `MultisampleState::default` instead")]
pub fn new() -> MultisampleState {
Self::default()
}
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
let &Self {
@ -129,11 +143,3 @@ impl MultisampleState {
Ok(())
}
}
impl Default for MultisampleState {
/// Returns [`MultisampleState::new()`].
#[inline]
fn default() -> Self {
Self::new()
}
}

View File

@ -10,8 +10,7 @@
//! Configures how primitives should be converted into collections of fragments.
use crate::{
device::Device, macros::vulkan_enum, pipeline::StateMode, Requires, RequiresAllOf,
RequiresOneOf, ValidationError, Version,
device::Device, macros::vulkan_enum, Requires, RequiresAllOf, RequiresOneOf, ValidationError,
};
/// The state in a graphics pipeline describing how the rasterization stage should behave.
@ -22,16 +21,16 @@ pub struct RasterizationState {
///
/// If enabled, the [`depth_clamp`](crate::device::Features::depth_clamp) feature must be
/// enabled on the device.
///
/// The default value is `false`.
pub depth_clamp_enable: bool,
/// If true, all the fragments will be discarded, and the fragment shader will not be run. This
/// is usually used when your vertex shader has some side effects and you don't need to run the
/// fragment shader.
///
/// If set to `Dynamic`, the device API version must be at least 1.3, or the
/// [`extended_dynamic_state2`](crate::device::Features::extended_dynamic_state2) feature must
/// be enabled on the device.
pub rasterizer_discard_enable: StateMode<bool>,
/// The default value is `false`.
pub rasterizer_discard_enable: bool,
/// This setting can ask the rasterizer to downgrade triangles into lines or points, or lines
/// into points.
@ -39,26 +38,26 @@ pub struct RasterizationState {
/// If set to a value other than `Fill`, the
/// [`fill_mode_non_solid`](crate::device::Features::fill_mode_non_solid) feature must be
/// enabled on the device.
///
/// The default value is [`PolygonMode::Fill`].
pub polygon_mode: PolygonMode,
/// Specifies whether front faces or back faces should be discarded, or none, or both.
///
/// If set to `Dynamic`, the device API version must be at least 1.3, or the
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature must be
/// enabled on the device.
pub cull_mode: StateMode<CullMode>,
/// The default value is [`CullMode::None`].
pub cull_mode: CullMode,
/// Specifies which triangle orientation is considered to be the front of the triangle.
///
/// If set to `Dynamic`, the device API version must be at least 1.3, or the
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature must be
/// enabled on the device.
pub front_face: StateMode<FrontFace>,
/// The default value is [`FrontFace::CounterClockwise`].
pub front_face: FrontFace,
/// Sets how to modify depth values in the rasterization stage.
///
/// If set to `None`, depth biasing is disabled, the depth values will pass to the fragment
/// shader unmodified.
///
/// The default value is `None`.
pub depth_bias: Option<DepthBiasState>,
/// Width, in pixels, of lines when drawing lines.
@ -66,13 +65,17 @@ pub struct RasterizationState {
/// Setting this to a value other than 1.0 requires the
/// [`wide_lines`](crate::device::Features::wide_lines) feature to be enabled on
/// the device.
pub line_width: StateMode<f32>,
///
/// The default value is `1.0`.
pub line_width: f32,
/// The rasterization mode for lines.
///
/// If this is not set to `Default`, the
/// [`ext_line_rasterization`](crate::device::DeviceExtensions::ext_line_rasterization)
/// extension and an additional feature must be enabled on the device.
///
/// The default value is [`LineRasterizationMode::Default`].
pub line_rasterization_mode: LineRasterizationMode,
/// Enables and sets the parameters for line stippling.
@ -80,33 +83,44 @@ pub struct RasterizationState {
/// If this is set to `Some`, the
/// [`ext_line_rasterization`](crate::device::DeviceExtensions::ext_line_rasterization)
/// extension and an additional feature must be enabled on the device.
pub line_stipple: Option<StateMode<LineStipple>>,
///
/// The default value is `None`.
pub line_stipple: Option<LineStipple>,
pub _ne: crate::NonExhaustive,
}
impl Default for RasterizationState {
#[inline]
fn default() -> Self {
Self {
depth_clamp_enable: false,
rasterizer_discard_enable: false,
polygon_mode: Default::default(),
cull_mode: Default::default(),
front_face: Default::default(),
depth_bias: None,
line_width: 1.0,
line_rasterization_mode: Default::default(),
line_stipple: None,
_ne: crate::NonExhaustive(()),
}
}
}
impl RasterizationState {
/// Creates a `RasterizationState` with depth clamping, discard, depth biasing and line
/// stippling disabled, filled polygons, no culling, counterclockwise front face, and the
/// default line width and line rasterization mode.
#[inline]
#[deprecated(since = "0.34.0", note = "use `RasterizationState::default` instead")]
pub fn new() -> Self {
Self {
depth_clamp_enable: false,
rasterizer_discard_enable: StateMode::Fixed(false),
polygon_mode: Default::default(),
cull_mode: StateMode::Fixed(Default::default()),
front_face: StateMode::Fixed(Default::default()),
depth_bias: None,
line_width: StateMode::Fixed(1.0),
line_rasterization_mode: Default::default(),
line_stipple: None,
_ne: crate::NonExhaustive(()),
}
Self::default()
}
/// Sets the polygon mode.
#[inline]
#[deprecated(since = "0.34.0")]
pub fn polygon_mode(mut self, polygon_mode: PolygonMode) -> Self {
self.polygon_mode = polygon_mode;
self
@ -114,29 +128,17 @@ impl RasterizationState {
/// Sets the cull mode.
#[inline]
#[deprecated(since = "0.34.0")]
pub fn cull_mode(mut self, cull_mode: CullMode) -> Self {
self.cull_mode = StateMode::Fixed(cull_mode);
self
}
/// Sets the cull mode to dynamic.
#[inline]
pub fn cull_mode_dynamic(mut self) -> Self {
self.cull_mode = StateMode::Dynamic;
self.cull_mode = cull_mode;
self
}
/// Sets the front face.
#[inline]
#[deprecated(since = "0.34.0")]
pub fn front_face(mut self, front_face: FrontFace) -> Self {
self.front_face = StateMode::Fixed(front_face);
self
}
/// Sets the front face to dynamic.
#[inline]
pub fn front_face_dynamic(mut self) -> Self {
self.front_face = StateMode::Dynamic;
self.front_face = front_face;
self
}
@ -147,8 +149,8 @@ impl RasterizationState {
polygon_mode,
cull_mode,
front_face,
ref depth_bias,
line_width,
depth_bias: _,
line_width: _,
line_rasterization_mode,
ref line_stipple,
_ne: _,
@ -187,145 +189,34 @@ impl RasterizationState {
}));
}
match rasterizer_discard_enable {
StateMode::Fixed(false) => {
if device.enabled_extensions().khr_portability_subset
&& !device.enabled_features().point_polygons
&& polygon_mode == PolygonMode::Point
{
return Err(Box::new(ValidationError {
problem: "this device is a portability subset device, \
`rasterizer_discard_enable` is `false`, and \
`polygon_mode` is `PolygonMode::Point`"
.into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
"point_polygons",
)])]),
vuids: &["VUID-VkPipelineRasterizationStateCreateInfo-pointPolygons-04458"],
..Default::default()
}));
}
}
StateMode::Dynamic => {
if !(device.api_version() >= Version::V1_3
|| device.enabled_features().extended_dynamic_state2)
{
return Err(Box::new(ValidationError {
context: "rasterizer_discard_enable".into(),
problem: "is dynamic".into(),
requires_one_of: RequiresOneOf(&[
RequiresAllOf(&[Requires::APIVersion(Version::V1_3)]),
RequiresAllOf(&[Requires::Feature("extended_dynamic_state")]),
]),
// vuids?
..Default::default()
}));
}
}
_ => (),
}
match cull_mode {
StateMode::Fixed(cull_mode) => {
cull_mode.validate_device(device).map_err(|err| {
err.add_context("cull_mode").set_vuids(&[
"VUID-VkPipelineRasterizationStateCreateInfo-cullMode-parameter",
])
})?;
}
StateMode::Dynamic => {
if !(device.api_version() >= Version::V1_3
|| device.enabled_features().extended_dynamic_state)
{
return Err(Box::new(ValidationError {
context: "cull_mode".into(),
problem: "is dynamic".into(),
requires_one_of: RequiresOneOf(&[
RequiresAllOf(&[Requires::APIVersion(Version::V1_3)]),
RequiresAllOf(&[Requires::Feature("extended_dynamic_state")]),
]),
// vuids?
..Default::default()
}));
}
}
}
match front_face {
StateMode::Fixed(front_face) => {
front_face.validate_device(device).map_err(|err| {
err.add_context("front_face").set_vuids(&[
"VUID-VkPipelineRasterizationStateCreateInfo-frontFace-parameter",
])
})?;
}
StateMode::Dynamic => {
if !(device.api_version() >= Version::V1_3
|| device.enabled_features().extended_dynamic_state)
{
return Err(Box::new(ValidationError {
context: "front_face".into(),
problem: "is dynamic".into(),
requires_one_of: RequiresOneOf(&[
RequiresAllOf(&[Requires::APIVersion(Version::V1_3)]),
RequiresAllOf(&[Requires::Feature("extended_dynamic_state")]),
]),
// vuids?
..Default::default()
}));
}
}
}
if let Some(depth_bias_state) = depth_bias {
let &DepthBiasState {
enable_dynamic,
bias,
} = depth_bias_state;
if enable_dynamic
&& !(device.api_version() >= Version::V1_3
|| device.enabled_features().extended_dynamic_state2)
{
return Err(Box::new(ValidationError {
context: "depth_bias.enable_dynamic".into(),
problem: "is `true`".into(),
requires_one_of: RequiresOneOf(&[
RequiresAllOf(&[Requires::APIVersion(Version::V1_3)]),
RequiresAllOf(&[Requires::Feature("extended_dynamic_state2")]),
]),
// vuids?
..Default::default()
}));
}
if matches!(bias, StateMode::Fixed(bias) if bias.clamp != 0.0)
&& !device.enabled_features().depth_bias_clamp
{
return Err(Box::new(ValidationError {
context: "depth_bias.bias.clamp".into(),
problem: "is not 0.0".into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
"depth_bias_clamp",
)])]),
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00754"],
}));
}
}
if matches!(line_width, StateMode::Fixed(line_width) if line_width != 1.0)
&& !device.enabled_features().wide_lines
if device.enabled_extensions().khr_portability_subset
&& !device.enabled_features().point_polygons
&& !rasterizer_discard_enable
&& polygon_mode == PolygonMode::Point
{
return Err(Box::new(ValidationError {
context: "line_width".into(),
problem: "is not 1.0".into(),
problem: "this device is a portability subset device, \
`rasterizer_discard_enable` is `false`, and \
`polygon_mode` is `PolygonMode::Point`"
.into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
"wide_lines",
"point_polygons",
)])]),
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00749"],
vuids: &["VUID-VkPipelineRasterizationStateCreateInfo-pointPolygons-04458"],
..Default::default()
}));
}
cull_mode.validate_device(device).map_err(|err| {
err.add_context("cull_mode")
.set_vuids(&["VUID-VkPipelineRasterizationStateCreateInfo-cullMode-parameter"])
})?;
front_face.validate_device(device).map_err(|err| {
err.add_context("front_face")
.set_vuids(&["VUID-VkPipelineRasterizationStateCreateInfo-frontFace-parameter"])
})?;
if line_rasterization_mode != LineRasterizationMode::Default {
if !device.enabled_extensions().ext_line_rasterization {
return Err(Box::new(ValidationError {
@ -379,7 +270,7 @@ impl RasterizationState {
}
}
if let Some(line_stipple) = line_stipple {
if line_stipple.is_some() {
if !device.enabled_extensions().ext_line_rasterization {
return Err(Box::new(ValidationError {
context: "line_stipple".into(),
@ -391,19 +282,6 @@ impl RasterizationState {
}));
}
if let StateMode::Fixed(line_stipple) = line_stipple {
let &LineStipple { factor, pattern: _ } = line_stipple;
if !(1..=256).contains(&factor) {
return Err(Box::new(ValidationError {
context: "line_stipple.factor".into(),
problem: "is not between 1 and 256 inclusive".into(),
vuids: &["VUID-VkGraphicsPipelineCreateInfo-stippledLineEnable-02767"],
..Default::default()
}));
}
}
match line_rasterization_mode {
LineRasterizationMode::Default => {
if !device.enabled_features().stippled_rectangular_lines {
@ -479,33 +357,12 @@ impl RasterizationState {
}
}
impl Default for RasterizationState {
/// Returns [`RasterizationState::new()`].
#[inline]
fn default() -> Self {
Self::new()
}
}
/// The state in a graphics pipeline describing how depth biasing should behave when enabled.
#[derive(Clone, Copy, Debug)]
pub struct DepthBiasState {
/// Sets whether depth biasing should be enabled and disabled dynamically. If set to `false`,
/// depth biasing is always enabled.
///
/// If set to `true`, the
/// [`extended_dynamic_state2`](crate::device::Features::extended_dynamic_state2) feature must
/// be enabled on the device.
pub enable_dynamic: bool,
/// The values to use when depth biasing is enabled.
pub bias: StateMode<DepthBias>,
}
/// The values to use for depth biasing.
#[derive(Clone, Copy, Debug)]
pub struct DepthBias {
/// Specifies a constant factor to be added to every depth value.
pub struct DepthBiasState {
/// Specifies a constant factor to be multiplied to every depth value.
///
/// The default value is `1.0`.
pub constant_factor: f32,
/// The maximum (or minimum) depth bias of a fragment.
@ -513,12 +370,27 @@ pub struct DepthBias {
/// Setting this to a value other than 0.0 requires the
/// [`depth_bias_clamp`](crate::device::Features::depth_bias_clamp) feature to be enabled on
/// the device.
///
/// The default value is `0.0`.
pub clamp: f32,
/// A scalar factor applied to a fragment's slope in depth bias calculations.
/// A scalar factor to multiply with a fragment's slope in depth bias calculations.
///
/// The default value is `1.0`.
pub slope_factor: f32,
}
impl Default for DepthBiasState {
#[inline]
fn default() -> Self {
Self {
constant_factor: 1.0,
clamp: 0.0,
slope_factor: 1.0,
}
}
}
vulkan_enum! {
#[non_exhaustive]
@ -560,7 +432,6 @@ vulkan_enum! {
/// as facing their front. Otherwise they will be considered as facing their back.
CounterClockwise = COUNTER_CLOCKWISE,
/// Triangles whose vertices are oriented clockwise on the screen will be considered
/// as facing their front. Otherwise they will be considered as facing their back.
Clockwise = CLOCKWISE,
@ -660,6 +531,7 @@ impl Default for LineRasterizationMode {
pub struct LineStipple {
/// The repeat factor used in stippled line rasterization. Must be between 1 and 256 inclusive.
pub factor: u32,
/// The bit pattern used in stippled line rasterization.
pub pattern: u16,
}

View File

@ -10,8 +10,8 @@
//! Subdivides primitives into smaller primitives.
use crate::{
device::Device, macros::vulkan_enum, pipeline::StateMode, Requires, RequiresAllOf,
RequiresOneOf, ValidationError, Version,
device::Device, macros::vulkan_enum, Requires, RequiresAllOf, RequiresOneOf, ValidationError,
Version,
};
/// The state in a graphics pipeline describing the tessellation shader execution of a graphics
@ -20,10 +20,8 @@ use crate::{
pub struct TessellationState {
/// The number of patch control points to use.
///
/// If set to `Dynamic`, the
/// [`extended_dynamic_state2_patch_control_points`](crate::device::Features::extended_dynamic_state2_patch_control_points)
/// feature must be enabled on the device.
pub patch_control_points: StateMode<u32>,
/// The default value is 3.
pub patch_control_points: u32,
/// The origin to use for the tessellation domain.
///
@ -37,31 +35,34 @@ pub struct TessellationState {
pub _ne: crate::NonExhaustive,
}
impl TessellationState {
/// Creates a new `TessellationState` with 3 patch control points.
impl Default for TessellationState {
#[inline]
pub fn new() -> Self {
fn default() -> Self {
Self {
patch_control_points: StateMode::Fixed(3),
patch_control_points: 3,
domain_origin: TessellationDomainOrigin::default(),
_ne: crate::NonExhaustive(()),
}
}
}
impl TessellationState {
/// Creates a new `TessellationState` with 3 patch control points.
#[inline]
#[deprecated(since = "0.34.0", note = "use `TessellationState::default` instead")]
pub fn new() -> Self {
Self::default()
}
/// Sets the number of patch control points.
#[inline]
#[deprecated(since = "0.34.0")]
pub fn patch_control_points(mut self, num: u32) -> Self {
self.patch_control_points = StateMode::Fixed(num);
self
}
/// Sets the number of patch control points to dynamic.
#[inline]
pub fn patch_control_points_dynamic(mut self) -> Self {
self.patch_control_points = StateMode::Dynamic;
self.patch_control_points = num;
self
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
let &Self {
patch_control_points,
@ -71,46 +72,23 @@ impl TessellationState {
let properties = device.physical_device().properties();
match patch_control_points {
StateMode::Fixed(patch_control_points) => {
if patch_control_points == 0 {
return Err(Box::new(ValidationError {
context: "patch_control_points".into(),
problem: "is zero".into(),
vuids: &[
"VUID-VkPipelineTessellationStateCreateInfo-patchControlPoints-01214",
],
..Default::default()
}));
}
if patch_control_points == 0 {
return Err(Box::new(ValidationError {
context: "patch_control_points".into(),
problem: "is zero".into(),
vuids: &["VUID-VkPipelineTessellationStateCreateInfo-patchControlPoints-01214"],
..Default::default()
}));
}
if patch_control_points > properties.max_tessellation_patch_size {
return Err(Box::new(ValidationError {
context: "patch_control_points".into(),
problem: "exceeds the `max_tessellation_patch_size` limit".into(),
vuids: &[
"VUID-VkPipelineTessellationStateCreateInfo-patchControlPoints-01214",
],
..Default::default()
}));
}
}
StateMode::Dynamic => {
if !device
.enabled_features()
.extended_dynamic_state2_patch_control_points
{
return Err(Box::new(ValidationError {
context: "patch_control_points".into(),
problem: "is dynamic".into(),
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature(
"extended_dynamic_state2_patch_control_points",
)])]),
vuids: &["VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-04870"],
}));
}
}
};
if patch_control_points > properties.max_tessellation_patch_size {
return Err(Box::new(ValidationError {
context: "patch_control_points".into(),
problem: "exceeds the `max_tessellation_patch_size` limit".into(),
vuids: &["VUID-VkPipelineTessellationStateCreateInfo-patchControlPoints-01214"],
..Default::default()
}));
}
domain_origin.validate_device(device).map_err(|err| {
err.add_context("domain_origin").set_vuids(&[
@ -137,14 +115,6 @@ impl TessellationState {
}
}
impl Default for TessellationState {
/// Returns [`TessellationState::new()`].
#[inline]
fn default() -> Self {
Self::new()
}
}
vulkan_enum! {
#[non_exhaustive]

View File

@ -17,7 +17,7 @@ use crate::{
/// 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`"
note = "use `VertexBufferDescription` directly instead as returned by `Vertex::per_vertex` or `Vertex::per_instance`"
)]
#[derive(Clone, Debug, Default)]
pub struct BuffersDefinition(Vec<VertexBufferDescription>);

View File

@ -97,7 +97,7 @@ macro_rules! impl_vertex {
/// Trait for data types that can be used as vertex members. Used by the `impl_vertex!` macro.
#[deprecated(
since = "0.33.0",
note = "Derive `Vertex` instead and use field-level attributes to specify format"
note = "derive `Vertex` instead and use field-level attributes to specify format"
)]
pub unsafe trait VertexMember {
/// Returns the format and array size of the member.

View File

@ -48,11 +48,7 @@
//! In all cases the number of viewports and scissor boxes must be the same.
//!
use crate::{
device::Device,
pipeline::{PartialStateMode, StateMode},
Requires, RequiresAllOf, RequiresOneOf, ValidationError, Version,
};
use crate::{device::Device, Requires, RequiresAllOf, RequiresOneOf, ValidationError, Version};
use smallvec::{smallvec, SmallVec};
use std::ops::RangeInclusive;
@ -63,125 +59,90 @@ use std::ops::RangeInclusive;
pub struct ViewportState {
/// Specifies the viewport transforms.
///
/// If the value is `PartialStateMode::Dynamic`, then the viewports are set dynamically, but
/// the number of viewports is still fixed.
///
/// If the value is `PartialStateMode::Dynamic(StateMode::Dynamic)`, then the number of
/// viewports is also dynamic. The device API version must be at least 1.3, or the
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature must
/// be enabled on the device.
/// When [`DynamicState::Viewport`] is used, the values of each viewport are ignored
/// and must be set dynamically, but the number of viewports is fixed and
/// must be matched when setting the dynamic value.
/// When [`DynamicState::ViewportWithCount`] is used, the number of viewports is also dynamic,
/// and `viewports` must be empty.
///
/// If neither the number of viewports nor the number of scissors is dynamic, then the
/// number of both must be identical.
///
/// The default value is `PartialStateMode::Fixed` with no viewports.
pub viewports: PartialStateMode<SmallVec<[Viewport; 1]>, StateMode<u32>>,
/// The default value is a single element of `Viewport::default()`.
///
/// [`DynamicState::Viewport`]: crate::pipeline::DynamicState::Viewport
/// [`DynamicState::ViewportWithCount`]: crate::pipeline::DynamicState::ViewportWithCount
pub viewports: SmallVec<[Viewport; 1]>,
/// Specifies the scissor rectangles.
///
/// If the value is `PartialStateMode::Dynamic`, then the scissors are set dynamically, but
/// the number of scissors is still fixed.
///
/// If the value is `PartialStateMode::Dynamic(StateMode::Dynamic)`, then the number of
/// scissors is also dynamic. The device API version must be at least 1.3, or the
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature must
/// be enabled on the device.
/// When [`DynamicState::Scissor`] is used, the values of each scissor are ignored
/// and must be set dynamically, but the number of scissors is fixed and
/// must be matched when setting the dynamic value.
/// When [`DynamicState::ScissorWithCount`] is used, the number of scissors is also dynamic,
/// and `scissors` must be empty.
///
/// If neither the number of viewports nor the number of scissors is dynamic, then the
/// number of both must be identical.
///
/// The default value is `PartialStateMode::Fixed` with no scissors.
pub scissors: PartialStateMode<SmallVec<[Scissor; 1]>, StateMode<u32>>,
/// The default value is a single element of `Scissor::default()`.
///
/// [`DynamicState::Scissor`]: crate::pipeline::DynamicState::Scissor
/// [`DynamicState::ScissorWithCount`]: crate::pipeline::DynamicState::ScissorWithCount
pub scissors: SmallVec<[Scissor; 1]>,
pub _ne: crate::NonExhaustive,
}
impl Default for ViewportState {
#[inline]
fn default() -> Self {
Self {
viewports: smallvec![Viewport::default()],
scissors: smallvec![Scissor::default()],
_ne: crate::NonExhaustive(()),
}
}
}
impl ViewportState {
/// Creates a `ViewportState` with fixed state and no viewports or scissors.
#[deprecated(since = "0.34.0")]
#[inline]
pub fn new() -> Self {
Self {
viewports: PartialStateMode::Fixed(SmallVec::new()),
scissors: PartialStateMode::Fixed(SmallVec::new()),
viewports: SmallVec::new(),
scissors: SmallVec::new(),
_ne: crate::NonExhaustive(()),
}
}
/// Creates a `ViewportState` with fixed state from the given viewports and scissors.
#[deprecated(since = "0.34.0")]
pub fn viewport_fixed_scissor_fixed(
data: impl IntoIterator<Item = (Viewport, Scissor)>,
) -> Self {
let (viewports, scissors) = data.into_iter().unzip();
Self {
viewports: PartialStateMode::Fixed(viewports),
scissors: PartialStateMode::Fixed(scissors),
viewports,
scissors,
_ne: crate::NonExhaustive(()),
}
}
/// Creates a `ViewportState` with fixed state from the given viewports, and matching scissors
/// that cover the whole viewport.
#[deprecated(since = "0.34.0")]
pub fn viewport_fixed_scissor_irrelevant(data: impl IntoIterator<Item = Viewport>) -> Self {
let viewports: SmallVec<_> = data.into_iter().collect();
let scissors = smallvec![Scissor::irrelevant(); viewports.len()];
let scissors = smallvec![Scissor::default(); viewports.len()];
Self {
viewports: PartialStateMode::Fixed(viewports),
scissors: PartialStateMode::Fixed(scissors),
viewports,
scissors,
_ne: crate::NonExhaustive(()),
}
}
/// Creates a `ViewportState` with dynamic viewport, and a single scissor that always covers
/// the whole viewport.
#[inline]
pub fn viewport_dynamic_scissor_irrelevant() -> Self {
Self {
viewports: PartialStateMode::Dynamic(StateMode::Fixed(1)),
scissors: PartialStateMode::Fixed(smallvec![Scissor::irrelevant(); 1]),
_ne: crate::NonExhaustive(()),
}
}
/// Creates a `ViewportState` with dynamic viewports and scissors, but a fixed count.
#[inline]
pub fn viewport_dynamic_scissor_dynamic(count: u32) -> Self {
Self {
viewports: PartialStateMode::Dynamic(StateMode::Fixed(count)),
scissors: PartialStateMode::Dynamic(StateMode::Fixed(count)),
_ne: crate::NonExhaustive(()),
}
}
/// Creates a `ViewportState` with dynamic viewport count and scissor count.
#[inline]
pub fn viewport_count_dynamic_scissor_count_dynamic() -> Self {
Self {
viewports: PartialStateMode::Dynamic(StateMode::Dynamic),
scissors: PartialStateMode::Dynamic(StateMode::Dynamic),
_ne: crate::NonExhaustive(()),
}
}
/// Returns the number of viewports and scissors.
///
/// `None` is returned if both counts are dynamic.
#[inline]
pub(crate) fn count(&self) -> Option<u32> {
match &self.viewports {
PartialStateMode::Fixed(viewports) => return Some(viewports.len() as u32),
PartialStateMode::Dynamic(StateMode::Fixed(count)) => return Some(*count),
PartialStateMode::Dynamic(StateMode::Dynamic) => (),
}
match &self.scissors {
PartialStateMode::Fixed(scissors) => return Some(scissors.len() as u32),
PartialStateMode::Dynamic(StateMode::Fixed(count)) => return Some(*count),
PartialStateMode::Dynamic(StateMode::Dynamic) => (),
}
None
}
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
let Self {
viewports,
@ -191,117 +152,46 @@ impl ViewportState {
let properties = device.physical_device().properties();
let viewport_count = match viewports {
PartialStateMode::Fixed(viewports) => {
if viewports.is_empty() {
return Err(Box::new(ValidationError {
context: "viewports".into(),
problem: "is empty".into(),
vuids: &["VUID-VkPipelineViewportStateCreateInfo-viewportCount-04135"],
..Default::default()
}));
}
for (index, viewport) in viewports.iter().enumerate() {
viewport
.validate(device)
.map_err(|err| err.add_context(format!("viewports[{}].0", index)))?;
}
viewports.len() as u32
}
PartialStateMode::Dynamic(StateMode::Fixed(count)) => {
if *count == 0 {
return Err(Box::new(ValidationError {
context: "viewports".into(),
problem: "is empty".into(),
vuids: &["VUID-VkPipelineViewportStateCreateInfo-viewportCount-04135"],
..Default::default()
}));
}
*count
}
PartialStateMode::Dynamic(StateMode::Dynamic) => {
// VUID-VkPipelineViewportStateCreateInfo-viewportCount-04135
0
}
};
let scissor_count = match scissors {
PartialStateMode::Fixed(scissors) => {
if scissors.is_empty() {
return Err(Box::new(ValidationError {
context: "scissors".into(),
problem: "is empty".into(),
vuids: &["VUID-VkPipelineViewportStateCreateInfo-scissorCount-04136"],
..Default::default()
}));
}
for (index, scissor) in scissors.iter().enumerate() {
let &Scissor { offset, extent } = scissor;
// VUID-VkPipelineViewportStateCreateInfo-x-02821
// Ensured by the use of an unsigned integer.
if (i32::try_from(offset[0]).ok())
.zip(i32::try_from(extent[0]).ok())
.and_then(|(o, e)| o.checked_add(e))
.is_none()
{
return Err(Box::new(ValidationError {
context: format!("scissors[{}]", index).into(),
problem: "`offset[0] + extent[0]` is greater than `i32::MAX`".into(),
vuids: &["VUID-VkPipelineViewportStateCreateInfo-offset-02822"],
..Default::default()
}));
}
if (i32::try_from(offset[1]).ok())
.zip(i32::try_from(extent[1]).ok())
.and_then(|(o, e)| o.checked_add(e))
.is_none()
{
return Err(Box::new(ValidationError {
context: format!("scissors[{}]", index).into(),
problem: "`offset[1] + extent[1]` is greater than `i32::MAX`".into(),
vuids: &["VUID-VkPipelineViewportStateCreateInfo-offset-02823"],
..Default::default()
}));
}
}
scissors.len() as u32
}
PartialStateMode::Dynamic(StateMode::Fixed(count)) => {
if *count == 0 {
return Err(Box::new(ValidationError {
context: "scissors".into(),
problem: "is empty".into(),
vuids: &["VUID-VkPipelineViewportStateCreateInfo-scissorCount-04136"],
..Default::default()
}));
}
*count
}
PartialStateMode::Dynamic(StateMode::Dynamic) => {
// VUID-VkPipelineViewportStateCreateInfo-scissorCount-04136
0
}
};
if viewport_count != 0 && scissor_count != 0 && viewport_count != scissor_count {
return Err(Box::new(ValidationError {
problem: "the length of `viewports` and the length of `scissors` are not equal"
.into(),
vuids: &["VUID-VkPipelineViewportStateCreateInfo-scissorCount-04134"],
..Default::default()
}));
for (index, viewport) in viewports.iter().enumerate() {
viewport
.validate(device)
.map_err(|err| err.add_context(format!("viewports[{}].0", index)))?;
}
if viewport_count > 1 && !device.enabled_features().multi_viewport {
for (index, scissor) in scissors.iter().enumerate() {
let &Scissor { offset, extent } = scissor;
// VUID-VkPipelineViewportStateCreateInfo-x-02821
// Ensured by the use of an unsigned integer.
if (i32::try_from(offset[0]).ok())
.zip(i32::try_from(extent[0]).ok())
.and_then(|(o, e)| o.checked_add(e))
.is_none()
{
return Err(Box::new(ValidationError {
context: format!("scissors[{}]", index).into(),
problem: "`offset[0] + extent[0]` is greater than `i32::MAX`".into(),
vuids: &["VUID-VkPipelineViewportStateCreateInfo-offset-02822"],
..Default::default()
}));
}
if (i32::try_from(offset[1]).ok())
.zip(i32::try_from(extent[1]).ok())
.and_then(|(o, e)| o.checked_add(e))
.is_none()
{
return Err(Box::new(ValidationError {
context: format!("scissors[{}]", index).into(),
problem: "`offset[1] + extent[1]` is greater than `i32::MAX`".into(),
vuids: &["VUID-VkPipelineViewportStateCreateInfo-offset-02823"],
..Default::default()
}));
}
}
if viewports.len() > 1 && !device.enabled_features().multi_viewport {
return Err(Box::new(ValidationError {
context: "viewports".into(),
problem: "the length is greater than 1".into(),
@ -312,7 +202,7 @@ impl ViewportState {
}));
}
if scissor_count > 1 && !device.enabled_features().multi_viewport {
if scissors.len() > 1 && !device.enabled_features().multi_viewport {
return Err(Box::new(ValidationError {
context: "scissors".into(),
problem: "the length is greater than 1".into(),
@ -323,7 +213,7 @@ impl ViewportState {
}));
}
if viewport_count > properties.max_viewports {
if viewports.len() > properties.max_viewports as usize {
return Err(Box::new(ValidationError {
context: "viewports".into(),
problem: "the length exceeds the `max_viewports` limit".into(),
@ -332,7 +222,7 @@ impl ViewportState {
}));
}
if scissor_count > properties.max_viewports {
if scissors.len() > properties.max_viewports as usize {
return Err(Box::new(ValidationError {
context: "scissors".into(),
problem: "the length exceeds the `max_viewports` limit".into(),
@ -345,21 +235,18 @@ impl ViewportState {
}
}
impl Default for ViewportState {
/// Returns [`ViewportState::new()`].
#[inline]
fn default() -> Self {
Self::new()
}
}
/// State of a single viewport.
#[derive(Debug, Clone, PartialEq)]
pub struct Viewport {
/// Coordinates in pixels of the top-left hand corner of the viewport.
///
/// The default value is `[0.0; 2]`.
pub offset: [f32; 2],
/// Dimensions in pixels of the viewport.
///
/// The default value is `[1.0; 2]`, which you probably want to override if you are not
/// using dynamic state.
pub extent: [f32; 2],
/// Minimum and maximum values of the depth.
@ -369,9 +256,22 @@ pub struct Viewport {
///
/// This is equivalents to `glDepthRange` in OpenGL, except that OpenGL uses the Z coordinate
/// range from `-1.0` to `1.0` instead.
///
/// The default value is `0.0..=1.0`.
pub depth_range: RangeInclusive<f32>,
}
impl Default for Viewport {
#[inline]
fn default() -> Self {
Self {
offset: [0.0; 2],
extent: [1.0; 2],
depth_range: 0.0..=1.0,
}
}
}
impl Viewport {
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
let &Self {
@ -525,28 +425,33 @@ impl From<&Viewport> for ash::vk::Viewport {
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Scissor {
/// Coordinates of the top-left hand corner of the box.
///
/// The default value is `[0; 2]`.
pub offset: [u32; 2],
/// Dimensions of the box.
///
/// The default value is `[i32::MAX; 2]`.
pub extent: [u32; 2],
}
impl Scissor {
/// Returns a scissor that, when used, will instruct the pipeline to draw to the entire
/// framebuffer no matter its size.
#[inline]
pub fn irrelevant() -> Scissor {
Scissor {
offset: [0, 0],
extent: [0x7fffffff, 0x7fffffff],
}
}
}
impl Default for Scissor {
#[inline]
fn default() -> Scissor {
Scissor::irrelevant()
Self {
offset: [0; 2],
extent: [i32::MAX as u32; 2],
}
}
}
impl Scissor {
/// Returns a scissor that, when used, will instruct the pipeline to draw to the entire
/// framebuffer no matter its size.
#[deprecated(since = "0.34.0", note = "use `Scissor::default` instead")]
#[inline]
pub fn irrelevant() -> Scissor {
Self::default()
}
}

View File

@ -945,441 +945,571 @@ vulkan_bitflags! {
vulkan_enum! {
#[non_exhaustive]
/// A particular state value within a graphics pipeline that can be dynamically set by a command
/// buffer.
/// A particular state value within a pipeline that can be dynamically set by a command buffer.
///
/// Whenever a particular state is set to be dynamic while creating the pipeline,
/// the corresponding predefined value in the pipeline's create info is ignored, unless
/// specified otherwise here.
///
/// If the dynamic state is used to enable/disable a certain functionality,
/// and the value in the create info is an `Option`
/// (for example, [`DynamicState::DepthTestEnable`] and [`DepthStencilState::depth`]),
/// then that `Option` must be `Some` when creating the pipeline,
/// in order to provide settings to use when the functionality is enabled.
///
/// [`DepthStencilState::depth`]: (crate::pipeline::graphics::depth_stencil::DepthStencilState::depth)
DynamicState = DynamicState(i32);
// TODO: document
/// The elements, but not the count, of
/// [`ViewportState::viewports`](crate::pipeline::graphics::viewport::ViewportState::viewports).
///
/// Set with
/// [`set_viewport`](crate::command_buffer::AutoCommandBufferBuilder::set_viewport).
Viewport = VIEWPORT,
// TODO: document
/// The elements, but not the count, of
/// [`ViewportState::scissors`](crate::pipeline::graphics::viewport::ViewportState::scissors).
///
/// Set with
/// [`set_scissor`](crate::command_buffer::AutoCommandBufferBuilder::set_scissor).
Scissor = SCISSOR,
// TODO: document
/// The value of
/// [`RasterizationState::line_width`](crate::pipeline::graphics::rasterization::RasterizationState::line_width).
///
/// Set with
/// [`set_line_width`](crate::command_buffer::AutoCommandBufferBuilder::set_line_width).
LineWidth = LINE_WIDTH,
// TODO: document
/// The value of
/// [`RasterizationState::depth_bias`](crate::pipeline::graphics::rasterization::RasterizationState::depth_bias).
///
/// Set with
/// [`set_depth_bias`](crate::command_buffer::AutoCommandBufferBuilder::set_depth_bias).
DepthBias = DEPTH_BIAS,
// TODO: document
/// The value of
/// [`ColorBlendState::blend_constants`](crate::pipeline::graphics::color_blend::ColorBlendState::blend_constants).
///
/// Set with
/// [`set_blend_constants`](crate::command_buffer::AutoCommandBufferBuilder::set_blend_constants).
BlendConstants = BLEND_CONSTANTS,
// TODO: document
/// The value, but not the `Option` variant, of
/// [`DepthStencilState::depth_bounds`](crate::pipeline::graphics::depth_stencil::DepthStencilState::depth_bounds).
///
/// Set with
/// [`set_depth_bounds`](crate::command_buffer::AutoCommandBufferBuilder::set_depth_bounds).
DepthBounds = DEPTH_BOUNDS,
// TODO: document
/// The value of
/// [`StencilOpState::compare_mask`](crate::pipeline::graphics::depth_stencil::StencilOpState::compare_mask)
/// for both the front and back face.
///
/// Set with
/// [`set_stencil_compare_mask`](crate::command_buffer::AutoCommandBufferBuilder::set_stencil_compare_mask).
StencilCompareMask = STENCIL_COMPARE_MASK,
// TODO: document
/// The value of
/// [`StencilOpState::write_mask`](crate::pipeline::graphics::depth_stencil::StencilOpState::write_mask)
/// for both the front and back face.
///
/// Set with
/// [`set_stencil_write_mask`](crate::command_buffer::AutoCommandBufferBuilder::set_stencil_write_mask).
StencilWriteMask = STENCIL_WRITE_MASK,
// TODO: document
/// The value of
/// [`StencilOpState::reference`](crate::pipeline::graphics::depth_stencil::StencilOpState::reference)
/// for both the front and back face.
///
/// Set with
/// [`set_stencil_reference`](crate::command_buffer::AutoCommandBufferBuilder::set_stencil_reference).
StencilReference = STENCIL_REFERENCE,
// TODO: document
/// The value of
/// [`RasterizationState::cull_mode`](crate::pipeline::graphics::rasterization::RasterizationState::cull_mode).
///
/// Set with
/// [`set_cull_mode`](crate::command_buffer::AutoCommandBufferBuilder::set_cull_mode).
CullMode = CULL_MODE
RequiresOneOf([
RequiresAllOf([APIVersion(V1_3)]),
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state)]),
]),
// TODO: document
/// The value of
/// [`RasterizationState::front_face`](crate::pipeline::graphics::rasterization::RasterizationState::front_face).
///
/// Set with
/// [`set_front_face`](crate::command_buffer::AutoCommandBufferBuilder::set_front_face).
FrontFace = FRONT_FACE
RequiresOneOf([
RequiresAllOf([APIVersion(V1_3)]),
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state)]),
]),
// TODO: document
/// The value of
/// [`InputAssemblyState::topology`](crate::pipeline::graphics::input_assembly::InputAssemblyState::topology).
///
/// Set with
/// [`set_primitive_topology`](crate::command_buffer::AutoCommandBufferBuilder::set_primitive_topology).
PrimitiveTopology = PRIMITIVE_TOPOLOGY
RequiresOneOf([
RequiresAllOf([APIVersion(V1_3)]),
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state)]),
]),
// TODO: document
/// Both the elements and the count of
/// [`ViewportState::viewports`](crate::pipeline::graphics::viewport::ViewportState::viewports).
///
/// Set with
/// [`set_viewport_with_count`](crate::command_buffer::AutoCommandBufferBuilder::set_viewport_with_count).
ViewportWithCount = VIEWPORT_WITH_COUNT
RequiresOneOf([
RequiresAllOf([APIVersion(V1_3)]),
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state)]),
]),
// TODO: document
/// Both the elements and the count of
/// [`ViewportState::scissors`](crate::pipeline::graphics::viewport::ViewportState::scissors).
///
/// Set with
/// [`set_scissor_with_count`](crate::command_buffer::AutoCommandBufferBuilder::set_scissor_with_count).
ScissorWithCount = SCISSOR_WITH_COUNT
RequiresOneOf([
RequiresAllOf([APIVersion(V1_3)]),
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state)]),
]),
/* TODO: enable
// TODO: document
VertexInputBindingStride = VERTEX_INPUT_BINDING_STRIDE
RequiresOneOf([
RequiresAllOf([APIVersion(V1_3)]),
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state)]),
]),
]),*/
// TODO: document
/// The `Option` variant of
/// [`DepthStencilState::depth`](crate::pipeline::graphics::depth_stencil::DepthStencilState::depth).
///
/// Set with
/// [`set_depth_test_enable`](crate::command_buffer::AutoCommandBufferBuilder::set_depth_test_enable).
DepthTestEnable = DEPTH_TEST_ENABLE
RequiresOneOf([
RequiresAllOf([APIVersion(V1_3)]),
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state)]),
]),
// TODO: document
/// The value of
/// [`DepthState::write_enable`](crate::pipeline::graphics::depth_stencil::DepthState::write_enable).
///
/// Set with
/// [`set_depth_write_enable`](crate::command_buffer::AutoCommandBufferBuilder::set_depth_write_enable).
DepthWriteEnable = DEPTH_WRITE_ENABLE
RequiresOneOf([
RequiresAllOf([APIVersion(V1_3)]),
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state)]),
]),
// TODO: document
/// The value of
/// [`DepthState::compare_op`](crate::pipeline::graphics::depth_stencil::DepthState::compare_op).
///
/// Set with
/// [`set_depth_compare_op`](crate::command_buffer::AutoCommandBufferBuilder::set_depth_compare_op).
DepthCompareOp = DEPTH_COMPARE_OP
RequiresOneOf([
RequiresAllOf([APIVersion(V1_3)]),
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state)]),
]),
// TODO: document
/// The `Option` variant of
/// [`DepthStencilState::depth_bounds`](crate::pipeline::graphics::depth_stencil::DepthStencilState::depth_bounds).
///
/// Set with
/// [`set_depth_bounds_test_enable`](crate::command_buffer::AutoCommandBufferBuilder::set_depth_bounds_test_enable).
DepthBoundsTestEnable = DEPTH_BOUNDS_TEST_ENABLE
RequiresOneOf([
RequiresAllOf([APIVersion(V1_3)]),
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state)]),
]),
// TODO: document
/// The `Option` variant of
/// [`DepthStencilState::stencil`](crate::pipeline::graphics::depth_stencil::DepthStencilState::stencil).
///
/// Set with
/// [`set_stencil_test_enable`](crate::command_buffer::AutoCommandBufferBuilder::set_stencil_test_enable).
StencilTestEnable = STENCIL_TEST_ENABLE
RequiresOneOf([
RequiresAllOf([APIVersion(V1_3)]),
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state)]),
]),
// TODO: document
/// The value of
/// [`StencilOpState::ops`](crate::pipeline::graphics::depth_stencil::StencilOpState::ops)
/// for both the front and back face.
///
/// Set with
/// [`set_stencil_op`](crate::command_buffer::AutoCommandBufferBuilder::set_stencil_op).
StencilOp = STENCIL_OP
RequiresOneOf([
RequiresAllOf([APIVersion(V1_3)]),
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state)]),
]),
// TODO: document
/// The value of
/// [`RasterizationState::rasterizer_discard_enable`](crate::pipeline::graphics::rasterization::RasterizationState::rasterizer_discard_enable).
///
/// Set with
/// [`set_rasterizer_discard_enable`](crate::command_buffer::AutoCommandBufferBuilder::set_rasterizer_discard_enable).
RasterizerDiscardEnable = RASTERIZER_DISCARD_ENABLE
RequiresOneOf([
RequiresAllOf([APIVersion(V1_3)]),
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state2)]),
]),
// TODO: document
/// The `Option` variant of
/// [`RasterizationState::depth_bias`](crate::pipeline::graphics::rasterization::RasterizationState::depth_bias).
///
/// Set with
/// [`set_depth_bias_enable`](crate::command_buffer::AutoCommandBufferBuilder::set_depth_bias_enable).
DepthBiasEnable = DEPTH_BIAS_ENABLE
RequiresOneOf([
RequiresAllOf([APIVersion(V1_3)]),
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state2)]),
]),
// TODO: document
/// The value of
/// [`InputAssemblyState::primitive_restart_enable`](crate::pipeline::graphics::input_assembly::InputAssemblyState::primitive_restart_enable).
///
/// Set with
/// [`set_primitive_restart_enable`](crate::command_buffer::AutoCommandBufferBuilder::set_primitive_restart_enable).
PrimitiveRestartEnable = PRIMITIVE_RESTART_ENABLE
RequiresOneOf([
RequiresAllOf([APIVersion(V1_3)]),
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state2)]),
]),
/* TODO: enable
// TODO: document
ViewportWScaling = VIEWPORT_W_SCALING_NV
RequiresOneOf([
RequiresAllOf([DeviceExtension(nv_clip_space_w_scaling)]),
]),
]), */
// TODO: document
/// The elements, but not count, of
/// [`DiscardRectangleState::rectangles`](crate::pipeline::graphics::discard_rectangle::DiscardRectangleState::rectangles).
///
/// Set with
/// [`set_discard_rectangle`](crate::command_buffer::AutoCommandBufferBuilder::set_discard_rectangle).
DiscardRectangle = DISCARD_RECTANGLE_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_discard_rectangles)]),
]),
/* TODO: enable
// TODO: document
SampleLocations = SAMPLE_LOCATIONS_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_sample_locations)]),
]),
]), */
/* TODO: enable
// TODO: document
RayTracingPipelineStackSize = RAY_TRACING_PIPELINE_STACK_SIZE_KHR
RequiresOneOf([
RequiresAllOf([DeviceExtension(khr_ray_tracing_pipeline)]),
]),
]), */
/* TODO: enable
// TODO: document
ViewportShadingRatePalette = VIEWPORT_SHADING_RATE_PALETTE_NV
RequiresOneOf([
RequiresAllOf([DeviceExtension(nv_shading_rate_image)]),
]),
]), */
/* TODO: enable
// TODO: document
ViewportCoarseSampleOrder = VIEWPORT_COARSE_SAMPLE_ORDER_NV
RequiresOneOf([
RequiresAllOf([DeviceExtension(nv_shading_rate_image)]),
]),
]), */
/* TODO: enable
// TODO: document
ExclusiveScissor = EXCLUSIVE_SCISSOR_NV
RequiresOneOf([
RequiresAllOf([DeviceExtension(nv_scissor_exclusive)]),
]),
]), */
/* TODO: enable
// TODO: document
FragmentShadingRate = FRAGMENT_SHADING_RATE_KHR
RequiresOneOf([
RequiresAllOf([DeviceExtension(khr_fragment_shading_rate)]),
]),
]), */
// TODO: document
/// The value of
/// [`RasterizationState::line_stipple`](crate::pipeline::graphics::rasterization::RasterizationState::line_stipple).
///
/// Set with
/// [`set_line_stipple`](crate::command_buffer::AutoCommandBufferBuilder::set_line_stipple).
LineStipple = LINE_STIPPLE_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_line_rasterization)]),
]),
/* TODO: enable
// TODO: document
VertexInput = VERTEX_INPUT_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_vertex_input_dynamic_state)]),
]),
]), */
// TODO: document
/// The value of
/// [`TessellationState::patch_control_points`](crate::pipeline::graphics::tessellation::TessellationState::patch_control_points).
///
/// Set with
/// [`set_patch_control_points`](crate::command_buffer::AutoCommandBufferBuilder::set_patch_control_points).
PatchControlPoints = PATCH_CONTROL_POINTS_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state2)]),
]),
// TODO: document
/// The value of
/// [`ColorBlendState::logic_op`](crate::pipeline::graphics::color_blend::ColorBlendState::logic_op).
///
/// Set with
/// [`set_logic_op`](crate::command_buffer::AutoCommandBufferBuilder::set_logic_op).
LogicOp = LOGIC_OP_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state2)]),
]),
// TODO: document
/// The value of
/// [`ColorBlendAttachmentState::color_write_enable`](crate::pipeline::graphics::color_blend::ColorBlendAttachmentState::color_write_enable)
/// for every attachment.
///
/// Set with
/// [`set_color_write_enable`](crate::command_buffer::AutoCommandBufferBuilder::set_color_write_enable).
ColorWriteEnable = COLOR_WRITE_ENABLE_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_color_write_enable)]),
]),
/* TODO: enable
// TODO: document
TessellationDomainOrigin = TESSELLATION_DOMAIN_ORIGIN_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
DepthClampEnable = DEPTH_CLAMP_ENABLE_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
PolygonMode = POLYGON_MODE_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
RasterizationSamples = RASTERIZATION_SAMPLES_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
SampleMask = SAMPLE_MASK_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
AlphaToCoverageEnable = ALPHA_TO_COVERAGE_ENABLE_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
AlphaToOneEnable = ALPHA_TO_ONE_ENABLE_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
LogicOpEnable = LOGIC_OP_ENABLE_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
ColorBlendEnable = COLOR_BLEND_ENABLE_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
ColorBlendEquation = COLOR_BLEND_EQUATION_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
ColorWriteMask = COLOR_WRITE_MASK_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
RasterizationStream = RASTERIZATION_STREAM_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
ConservativeRasterizationMode = CONSERVATIVE_RASTERIZATION_MODE_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
ExtraPrimitiveOverestimationSize = EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
DepthClipEnable = DEPTH_CLIP_ENABLE_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
SampleLocationsEnable = SAMPLE_LOCATIONS_ENABLE_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
ColorBlendAdvanced = COLOR_BLEND_ADVANCED_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
ProvokingVertexMode = PROVOKING_VERTEX_MODE_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
LineRasterizationMode = LINE_RASTERIZATION_MODE_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
LineStippleEnable = LINE_STIPPLE_ENABLE_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
DepthClipNegativeOneToOne = DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
ViewportWScalingEnable = VIEWPORT_W_SCALING_ENABLE_NV
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
ViewportSwizzle = VIEWPORT_SWIZZLE_NV
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
CoverageToColorEnable = COVERAGE_TO_COLOR_ENABLE_NV
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
CoverageToColorLocation = COVERAGE_TO_COLOR_LOCATION_NV
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
CoverageModulationMode = COVERAGE_MODULATION_MODE_NV
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
CoverageModulationTableEnable = COVERAGE_MODULATION_TABLE_ENABLE_NV
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
CoverageModulationTable = COVERAGE_MODULATION_TABLE_NV
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
ShadingRateImageEnable = SHADING_RATE_IMAGE_ENABLE_NV
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
RepresentativeFragmentTestEnable = REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
]), */
/* TODO: enable
// TODO: document
CoverageReductionMode = COVERAGE_REDUCTION_MODE_NV
RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]),
]),
}
/// Specifies how a dynamic state is handled by a graphics pipeline.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum StateMode<F> {
/// The pipeline has a fixed value for this state. Previously set dynamic state will be lost
/// when binding it, and will have to be re-set after binding a pipeline that uses it.
Fixed(F),
/// The pipeline expects a dynamic value to be set by a command buffer. Previously set dynamic
/// state is not disturbed when binding it.
Dynamic,
}
impl<T> From<Option<T>> for StateMode<T> {
fn from(val: Option<T>) -> Self {
match val {
Some(x) => StateMode::Fixed(x),
None => StateMode::Dynamic,
}
}
}
impl<T> From<StateMode<T>> for Option<T> {
fn from(val: StateMode<T>) -> Self {
match val {
StateMode::Fixed(x) => Some(x),
StateMode::Dynamic => None,
}
}
}
/// A variant of `StateMode` that is used for cases where some value is still needed when the state
/// is dynamic.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum PartialStateMode<F, D> {
Fixed(F),
Dynamic(D),
]), */
}