mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-22 06:45:23 +00:00
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:
parent
5a98b0ba91
commit
0fed9bbc7f
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
},
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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,
|
||||
|
@ -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!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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.
|
||||
|
@ -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]
|
||||
|
||||
|
@ -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]
|
||||
|
||||
|
@ -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
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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]
|
||||
|
||||
|
@ -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>);
|
||||
|
@ -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.
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
]), */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user