Skip to content

Commit

Permalink
Add support for pipeline derivatives (#2299)
Browse files Browse the repository at this point in the history
* Add support for pipeline derivatives

* Doc derp

* Formatting

---------

Co-authored-by: marc0246 <[email protected]>
  • Loading branch information
Rua and marc0246 authored Aug 24, 2023
1 parent a99aa95 commit 15665c3
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 17 deletions.
66 changes: 62 additions & 4 deletions vulkano/src/pipeline/compute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand Down Expand Up @@ -90,6 +93,7 @@ impl ComputePipeline {
flags,
ref stage,
ref layout,
ref base_pipeline,
_ne: _,
} = &create_info;

Expand Down Expand Up @@ -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()
};

Expand Down Expand Up @@ -203,9 +209,10 @@ impl ComputePipeline {
create_info: ComputePipelineCreateInfo,
) -> Arc<ComputePipeline> {
let ComputePipelineCreateInfo {
flags: _,
flags,
stage,
layout,
base_pipeline: _,
_ne: _,
} = create_info;

Expand All @@ -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 {
Expand Down Expand Up @@ -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,
}

Expand All @@ -321,6 +346,7 @@ impl ComputePipelineCreateInfo {
flags: PipelineCreateFlags::empty(),
stage,
layout,
base_pipeline: None,
_ne: crate::NonExhaustive(()),
}
}
Expand All @@ -330,6 +356,7 @@ impl ComputePipelineCreateInfo {
flags,
ref stage,
ref layout,
ref base_pipeline,
_ne: _,
} = self;

Expand All @@ -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,
Expand Down
68 changes: 61 additions & 7 deletions vulkano/src/pipeline/graphics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand Down Expand Up @@ -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: _,
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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()
};

Expand Down Expand Up @@ -1184,7 +1188,7 @@ impl GraphicsPipeline {
create_info: GraphicsPipelineCreateInfo,
) -> Arc<Self> {
let GraphicsPipelineCreateInfo {
flags: _,
flags,
stages,

vertex_input_state,
Expand All @@ -1197,7 +1201,8 @@ impl GraphicsPipeline {
color_blend_state,

layout,
subpass: render_pass,
subpass,
base_pipeline: _,

discard_rectangle_state,

Expand Down Expand Up @@ -1597,6 +1602,7 @@ impl GraphicsPipeline {
device: InstanceOwnedDebugWrapper(device),
id: Self::next_id(),

flags,
shaders,
descriptor_binding_requirements,
num_used_descriptor_sets,
Expand All @@ -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,
Expand All @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -1890,6 +1911,7 @@ impl GraphicsPipelineCreateInfo {
color_blend_state: None,
layout,
subpass: None,
base_pipeline: None,
discard_rectangle_state: None,
_ne: crate::NonExhaustive(()),
}
Expand All @@ -1911,6 +1933,7 @@ impl GraphicsPipelineCreateInfo {

ref layout,
ref subpass,
ref base_pipeline,

ref discard_rectangle_state,
_ne: _,
Expand All @@ -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
*/
Expand Down
10 changes: 4 additions & 6 deletions vulkano/src/pipeline/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 15665c3

Please sign in to comment.