mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-21 22:34:43 +00:00
Add support for pipeline derivatives (#2299)
* Add support for pipeline derivatives * Doc derp * Formatting --------- Co-authored-by: marc0246 <40955683+marc0246@users.noreply.github.com>
This commit is contained in:
parent
a99aa95e61
commit
15665c3437
@ -47,7 +47,10 @@ pub struct ComputePipeline {
|
||||
handle: ash::vk::Pipeline,
|
||||
device: InstanceOwnedDebugWrapper<Arc<Device>>,
|
||||
id: NonZeroU64,
|
||||
|
||||
flags: PipelineCreateFlags,
|
||||
layout: DeviceOwnedDebugWrapper<Arc<PipelineLayout>>,
|
||||
|
||||
descriptor_binding_requirements: HashMap<(u32, u32), DescriptorBindingRequirements>,
|
||||
num_used_descriptor_sets: u32,
|
||||
}
|
||||
@ -90,6 +93,7 @@ impl ComputePipeline {
|
||||
flags,
|
||||
ref stage,
|
||||
ref layout,
|
||||
ref base_pipeline,
|
||||
_ne: _,
|
||||
} = &create_info;
|
||||
|
||||
@ -166,8 +170,10 @@ impl ComputePipeline {
|
||||
flags: flags.into(),
|
||||
stage: stage_vk,
|
||||
layout: layout.handle(),
|
||||
base_pipeline_handle: ash::vk::Pipeline::null(),
|
||||
base_pipeline_index: 0,
|
||||
base_pipeline_handle: base_pipeline
|
||||
.as_ref()
|
||||
.map_or(ash::vk::Pipeline::null(), VulkanObject::handle),
|
||||
base_pipeline_index: -1,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
@ -203,9 +209,10 @@ impl ComputePipeline {
|
||||
create_info: ComputePipelineCreateInfo,
|
||||
) -> Arc<ComputePipeline> {
|
||||
let ComputePipelineCreateInfo {
|
||||
flags: _,
|
||||
flags,
|
||||
stage,
|
||||
layout,
|
||||
base_pipeline: _,
|
||||
_ne: _,
|
||||
} = create_info;
|
||||
|
||||
@ -227,17 +234,26 @@ impl ComputePipeline {
|
||||
handle,
|
||||
device: InstanceOwnedDebugWrapper(device),
|
||||
id: Self::next_id(),
|
||||
|
||||
flags,
|
||||
layout: DeviceOwnedDebugWrapper(layout),
|
||||
|
||||
descriptor_binding_requirements,
|
||||
num_used_descriptor_sets,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the `Device` this compute pipeline was created with.
|
||||
/// Returns the `Device` that the pipeline was created with.
|
||||
#[inline]
|
||||
pub fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
|
||||
/// Returns the flags that the pipeline was created with.
|
||||
#[inline]
|
||||
pub fn flags(&self) -> PipelineCreateFlags {
|
||||
self.flags
|
||||
}
|
||||
}
|
||||
|
||||
impl Pipeline for ComputePipeline {
|
||||
@ -310,6 +326,15 @@ pub struct ComputePipelineCreateInfo {
|
||||
/// There is no default value.
|
||||
pub layout: Arc<PipelineLayout>,
|
||||
|
||||
/// The pipeline to use as a base when creating this pipeline.
|
||||
///
|
||||
/// If this is `Some`, then `flags` must contain [`PipelineCreateFlags::DERIVATIVE`],
|
||||
/// and the `flags` of the provided pipeline must contain
|
||||
/// [`PipelineCreateFlags::ALLOW_DERIVATIVES`].
|
||||
///
|
||||
/// The default value is `None`.
|
||||
pub base_pipeline: Option<Arc<ComputePipeline>>,
|
||||
|
||||
pub _ne: crate::NonExhaustive,
|
||||
}
|
||||
|
||||
@ -321,6 +346,7 @@ impl ComputePipelineCreateInfo {
|
||||
flags: PipelineCreateFlags::empty(),
|
||||
stage,
|
||||
layout,
|
||||
base_pipeline: None,
|
||||
_ne: crate::NonExhaustive(()),
|
||||
}
|
||||
}
|
||||
@ -330,6 +356,7 @@ impl ComputePipelineCreateInfo {
|
||||
flags,
|
||||
ref stage,
|
||||
ref layout,
|
||||
ref base_pipeline,
|
||||
_ne: _,
|
||||
} = self;
|
||||
|
||||
@ -342,6 +369,37 @@ impl ComputePipelineCreateInfo {
|
||||
.validate(device)
|
||||
.map_err(|err| err.add_context("stage"))?;
|
||||
|
||||
if flags.intersects(PipelineCreateFlags::DERIVATIVE) {
|
||||
let base_pipeline = base_pipeline.as_ref().ok_or_else(|| {
|
||||
Box::new(ValidationError {
|
||||
problem: "`flags` contains `PipelineCreateFlags::DERIVATIVE`, but \
|
||||
`base_pipeline` is `None`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkComputePipelineCreateInfo-flags-07984"],
|
||||
..Default::default()
|
||||
})
|
||||
})?;
|
||||
|
||||
if !base_pipeline
|
||||
.flags()
|
||||
.intersects(PipelineCreateFlags::ALLOW_DERIVATIVES)
|
||||
{
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "base_pipeline.flags()".into(),
|
||||
problem: "does not contain `PipelineCreateFlags::ALLOW_DERIVATIVES`".into(),
|
||||
vuids: &["VUID-vkCreateComputePipelines-flags-00696"],
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
} else if base_pipeline.is_some() {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`flags` does not contain `PipelineCreateFlags::DERIVATIVE`, but \
|
||||
`base_pipeline` is `Some`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
|
||||
let &PipelineShaderStageCreateInfo {
|
||||
flags: _,
|
||||
ref entry_point,
|
||||
|
@ -125,6 +125,7 @@ pub struct GraphicsPipeline {
|
||||
device: InstanceOwnedDebugWrapper<Arc<Device>>,
|
||||
id: NonZeroU64,
|
||||
|
||||
flags: PipelineCreateFlags,
|
||||
// TODO: replace () with an object that describes the shaders in some way.
|
||||
shaders: HashMap<ShaderStage, ()>,
|
||||
descriptor_binding_requirements: HashMap<(u32, u32), DescriptorBindingRequirements>,
|
||||
@ -190,7 +191,8 @@ impl GraphicsPipeline {
|
||||
ref color_blend_state,
|
||||
|
||||
ref layout,
|
||||
subpass: ref render_pass,
|
||||
ref subpass,
|
||||
ref base_pipeline,
|
||||
|
||||
ref discard_rectangle_state,
|
||||
_ne: _,
|
||||
@ -1003,7 +1005,7 @@ impl GraphicsPipeline {
|
||||
}
|
||||
}
|
||||
|
||||
let render_pass = render_pass.as_ref().unwrap();
|
||||
let render_pass = subpass.as_ref().unwrap();
|
||||
let mut render_pass_vk = ash::vk::RenderPass::null();
|
||||
let mut subpass_vk = 0;
|
||||
let mut color_attachment_formats_vk: SmallVec<[_; 4]> = SmallVec::new();
|
||||
@ -1124,8 +1126,10 @@ impl GraphicsPipeline {
|
||||
layout: layout.handle(),
|
||||
render_pass: render_pass_vk,
|
||||
subpass: subpass_vk,
|
||||
base_pipeline_handle: ash::vk::Pipeline::null(), // TODO:
|
||||
base_pipeline_index: -1, // TODO:
|
||||
base_pipeline_handle: base_pipeline
|
||||
.as_ref()
|
||||
.map_or(ash::vk::Pipeline::null(), VulkanObject::handle),
|
||||
base_pipeline_index: -1,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
@ -1184,7 +1188,7 @@ impl GraphicsPipeline {
|
||||
create_info: GraphicsPipelineCreateInfo,
|
||||
) -> Arc<Self> {
|
||||
let GraphicsPipelineCreateInfo {
|
||||
flags: _,
|
||||
flags,
|
||||
stages,
|
||||
|
||||
vertex_input_state,
|
||||
@ -1197,7 +1201,8 @@ impl GraphicsPipeline {
|
||||
color_blend_state,
|
||||
|
||||
layout,
|
||||
subpass: render_pass,
|
||||
subpass,
|
||||
base_pipeline: _,
|
||||
|
||||
discard_rectangle_state,
|
||||
|
||||
@ -1597,6 +1602,7 @@ impl GraphicsPipeline {
|
||||
device: InstanceOwnedDebugWrapper(device),
|
||||
id: Self::next_id(),
|
||||
|
||||
flags,
|
||||
shaders,
|
||||
descriptor_binding_requirements,
|
||||
num_used_descriptor_sets,
|
||||
@ -1611,7 +1617,7 @@ impl GraphicsPipeline {
|
||||
depth_stencil_state,
|
||||
color_blend_state,
|
||||
layout: DeviceOwnedDebugWrapper(layout),
|
||||
subpass: render_pass.unwrap(),
|
||||
subpass: subpass.unwrap(),
|
||||
dynamic_state,
|
||||
|
||||
discard_rectangle_state,
|
||||
@ -1624,6 +1630,12 @@ impl GraphicsPipeline {
|
||||
&self.device
|
||||
}
|
||||
|
||||
/// Returns the flags that the pipeline was created with.
|
||||
#[inline]
|
||||
pub fn flags(&self) -> PipelineCreateFlags {
|
||||
self.flags
|
||||
}
|
||||
|
||||
/// Returns information about a particular shader.
|
||||
///
|
||||
/// `None` is returned if the pipeline does not contain this shader.
|
||||
@ -1863,6 +1875,15 @@ pub struct GraphicsPipelineCreateInfo {
|
||||
/// The default value is `None`.
|
||||
pub subpass: Option<PipelineSubpassType>,
|
||||
|
||||
/// The pipeline to use as a base when creating this pipeline.
|
||||
///
|
||||
/// If this is `Some`, then `flags` must contain [`PipelineCreateFlags::DERIVATIVE`],
|
||||
/// and the `flags` of the provided pipeline must contain
|
||||
/// [`PipelineCreateFlags::ALLOW_DERIVATIVES`].
|
||||
///
|
||||
/// The default value is `None`.
|
||||
pub base_pipeline: Option<Arc<GraphicsPipeline>>,
|
||||
|
||||
/// The discard rectangle state.
|
||||
///
|
||||
/// This state is always used if it is provided.
|
||||
@ -1890,6 +1911,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
color_blend_state: None,
|
||||
layout,
|
||||
subpass: None,
|
||||
base_pipeline: None,
|
||||
discard_rectangle_state: None,
|
||||
_ne: crate::NonExhaustive(()),
|
||||
}
|
||||
@ -1911,6 +1933,7 @@ impl GraphicsPipelineCreateInfo {
|
||||
|
||||
ref layout,
|
||||
ref subpass,
|
||||
ref base_pipeline,
|
||||
|
||||
ref discard_rectangle_state,
|
||||
_ne: _,
|
||||
@ -1921,6 +1944,37 @@ impl GraphicsPipelineCreateInfo {
|
||||
.set_vuids(&["VUID-VkGraphicsPipelineCreateInfo-flags-parameter"])
|
||||
})?;
|
||||
|
||||
if flags.intersects(PipelineCreateFlags::DERIVATIVE) {
|
||||
let base_pipeline = base_pipeline.as_ref().ok_or_else(|| {
|
||||
Box::new(ValidationError {
|
||||
problem: "`flags` contains `PipelineCreateFlags::DERIVATIVE`, but \
|
||||
`base_pipeline` is `None`"
|
||||
.into(),
|
||||
vuids: &["VUID-VkGraphicsPipelineCreateInfo-flags-07984"],
|
||||
..Default::default()
|
||||
})
|
||||
})?;
|
||||
|
||||
if !base_pipeline
|
||||
.flags()
|
||||
.intersects(PipelineCreateFlags::ALLOW_DERIVATIVES)
|
||||
{
|
||||
return Err(Box::new(ValidationError {
|
||||
context: "base_pipeline.flags()".into(),
|
||||
problem: "does not contain `PipelineCreateFlags::ALLOW_DERIVATIVES`".into(),
|
||||
vuids: &["VUID-vkCreateGraphicsPipelines-flags-00721"],
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
} else if base_pipeline.is_some() {
|
||||
return Err(Box::new(ValidationError {
|
||||
problem: "`flags` does not contain `PipelineCreateFlags::DERIVATIVE`, but \
|
||||
`base_pipeline` is `Some`"
|
||||
.into(),
|
||||
..Default::default()
|
||||
}));
|
||||
}
|
||||
|
||||
/*
|
||||
Gather shader stages
|
||||
*/
|
||||
|
@ -92,13 +92,11 @@ vulkan_bitflags! {
|
||||
/// The pipeline will not be optimized.
|
||||
DISABLE_OPTIMIZATION = DISABLE_OPTIMIZATION,
|
||||
|
||||
/* TODO: enable
|
||||
// TODO: document
|
||||
ALLOW_DERIVATIVES = ALLOW_DERIVATIVES,*/
|
||||
/// Derivative pipelines can be created using this pipeline as a base.
|
||||
ALLOW_DERIVATIVES = ALLOW_DERIVATIVES,
|
||||
|
||||
/* TODO: enable
|
||||
// TODO: document
|
||||
DERIVATIVE = DERIVATIVE,*/
|
||||
/// Create the pipeline by deriving from a base pipeline.
|
||||
DERIVATIVE = DERIVATIVE,
|
||||
|
||||
/* TODO: enable
|
||||
// TODO: document
|
||||
|
Loading…
Reference in New Issue
Block a user