Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add partial support for khr_fragment_shading_rate #2574

Merged
merged 9 commits into from
Oct 19, 2024
31 changes: 31 additions & 0 deletions vulkano-taskgraph/src/command_buffer/commands/dynamic_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use vulkano::{
pipeline::graphics::{
color_blend::LogicOp,
depth_stencil::{CompareOp, StencilFaces, StencilOp},
fragment_shading_rate::FragmentShadingRateCombinerOp,
input_assembly::PrimitiveTopology,
rasterization::{ConservativeRasterizationMode, CullMode, FrontFace},
vertex_input::{
Expand Down Expand Up @@ -772,4 +773,34 @@ impl RecordingCommandBuffer<'_> {

self
}

/// Sets the dynamic fragment shading rate for future draw calls.
pub unsafe fn set_fragment_shading_rate(
&mut self,
fragment_size: [u32; 2],
combiner_ops: [FragmentShadingRateCombinerOp; 2],
) -> Result<&mut Self> {
unsafe { Ok(self.set_fragment_shading_rate_unchecked(fragment_size, combiner_ops)) }
}

pub unsafe fn set_fragment_shading_rate_unchecked(
&mut self,
fragment_size: [u32; 2],
combiner_ops: [FragmentShadingRateCombinerOp; 2],
) -> &mut Self {
let fns = self.device().fns();
let fragment_size = vk::Extent2D {
width: fragment_size[0],
height: fragment_size[1],
};
let combiner_ops = [combiner_ops[0].into(), combiner_ops[1].into()];
unsafe {
(fns.khr_fragment_shading_rate
.cmd_set_fragment_shading_rate_khr)(
self.handle(), &fragment_size, &combiner_ops
)
}

self
}
}
4 changes: 3 additions & 1 deletion vulkano/src/command_buffer/auto/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use crate::{
graphics::{
color_blend::LogicOp,
depth_stencil::{CompareOp, StencilOps},
fragment_shading_rate::FragmentShadingRateState,
input_assembly::PrimitiveTopology,
rasterization::{
ConservativeRasterizationMode, CullMode, DepthBiasState, FrontFace, LineStipple,
Expand Down Expand Up @@ -1212,6 +1213,7 @@ pub(in crate::command_buffer) struct CommandBufferBuilderState {
pub(in crate::command_buffer) conservative_rasterization_mode:
Option<ConservativeRasterizationMode>,
pub(in crate::command_buffer) extra_primitive_overestimation_size: Option<f32>,
pub(in crate::command_buffer) fragment_shading_rate: Option<FragmentShadingRateState>,

// Active queries
pub(in crate::command_buffer) queries: HashMap<QueryType, QueryState>,
Expand Down Expand Up @@ -1243,7 +1245,7 @@ impl CommandBufferBuilderState {
DynamicState::DepthWriteEnable => self.depth_write_enable = None,
DynamicState::DiscardRectangle => self.discard_rectangle.clear(),
// DynamicState::ExclusiveScissor => todo!(),
// DynamicState::FragmentShadingRate => todo!(),
DynamicState::FragmentShadingRate => self.fragment_shading_rate = None,
DynamicState::FrontFace => self.front_face = None,
DynamicState::LineStipple => self.line_stipple = None,
DynamicState::LineWidth => self.line_width = None,
Expand Down
89 changes: 89 additions & 0 deletions vulkano/src/command_buffer/commands/dynamic_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::{
graphics::{
color_blend::LogicOp,
depth_stencil::{CompareOp, StencilFaces, StencilOp, StencilOps},
fragment_shading_rate::{FragmentShadingRateCombinerOp, FragmentShadingRateState},
input_assembly::PrimitiveTopology,
rasterization::{
ConservativeRasterizationMode, CullMode, DepthBiasState, FrontFace, LineStipple,
Expand Down Expand Up @@ -1280,6 +1281,54 @@ impl RecordingCommandBuffer {

self
}

/// Sets the dynamic fragment shading rate for future draw calls.
#[inline]
pub fn set_fragment_shading_rate(
&mut self,
fragment_size: [u32; 2],
combiner_ops: [FragmentShadingRateCombinerOp; 2],
) -> Result<&mut Self, Box<ValidationError>> {
self.validate_set_fragment_shading_rate(fragment_size, combiner_ops)?;

unsafe { Ok(self.set_fragment_shading_rate_unchecked(fragment_size, combiner_ops)) }
}

fn validate_set_fragment_shading_rate(
&self,
fragment_size: [u32; 2],
combiner_ops: [FragmentShadingRateCombinerOp; 2],
) -> Result<(), Box<ValidationError>> {
self.inner
.validate_set_fragment_shading_rate(fragment_size, combiner_ops)?;

self.validate_graphics_pipeline_fixed_state(DynamicState::FragmentShadingRate)?;

Ok(())
}

#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn set_fragment_shading_rate_unchecked(
&mut self,
fragment_size: [u32; 2],
combiner_ops: [FragmentShadingRateCombinerOp; 2],
) -> &mut Self {
self.builder_state.fragment_shading_rate = Some(FragmentShadingRateState {
fragment_size,
combiner_ops,
..FragmentShadingRateState::default()
});

self.add_command(
"set_fragment_shading_rate",
Default::default(),
move |out: &mut RawRecordingCommandBuffer| {
out.set_fragment_shading_rate_unchecked(fragment_size, combiner_ops);
},
);

self
}
}

impl RawRecordingCommandBuffer {
Expand Down Expand Up @@ -3381,4 +3430,44 @@ impl RawRecordingCommandBuffer {

self
}

fn validate_set_fragment_shading_rate(
&self,
fragment_size: [u32; 2],
combiner_ops: [FragmentShadingRateCombinerOp; 2],
) -> Result<(), Box<ValidationError>> {
FragmentShadingRateState {
fragment_size,
combiner_ops,
..FragmentShadingRateState::default()
}
.validate(self.device())?;

Ok(())
}

#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn set_fragment_shading_rate_unchecked(
&mut self,
fragment_size: [u32; 2],
combiner_ops: [FragmentShadingRateCombinerOp; 2],
) -> &mut Self {
let fns = self.device().fns();

let fragment_size = ash::vk::Extent2D {
width: fragment_size[0],
height: fragment_size[1],
};
let combiner_ops: [ash::vk::FragmentShadingRateCombinerOpKHR; 2] =
[combiner_ops[0].into(), combiner_ops[1].into()];

(fns.khr_fragment_shading_rate
.cmd_set_fragment_shading_rate_khr)(
self.handle(),
&fragment_size,
combiner_ops.as_ptr().cast(),
);

self
}
}
20 changes: 19 additions & 1 deletion vulkano/src/command_buffer/commands/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2633,7 +2633,25 @@ impl RecordingCommandBuffer {
}
}
// DynamicState::ExclusiveScissor => todo!(),
// DynamicState::FragmentShadingRate => todo!(),
DynamicState::FragmentShadingRate => {
if self.builder_state.fragment_shading_rate.is_none() {
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,
"VUID-vkCmdDrawIndexed-pipelineFragmentShadingRate-09238"
),
..Default::default()
}));
}
}
DynamicState::FrontFace => {
if self.builder_state.front_face.is_none() {
return Err(Box::new(ValidationError {
Expand Down
Loading