1use crate::command_buffer::{RecordingCommandBuffer, Result};
2use ash::vk;
3use smallvec::SmallVec;
4use std::ops::RangeInclusive;
5use vulkano::{
6 device::DeviceOwned,
7 pipeline::graphics::{
8 color_blend::LogicOp,
9 depth_stencil::{CompareOp, StencilFaces, StencilOp},
10 fragment_shading_rate::FragmentShadingRateCombinerOp,
11 input_assembly::PrimitiveTopology,
12 rasterization::{ConservativeRasterizationMode, CullMode, FrontFace},
13 vertex_input::{
14 VertexInputAttributeDescription, VertexInputBindingDescription, VertexInputState,
15 },
16 viewport::{Scissor, Viewport},
17 },
18 Version, VulkanObject,
19};
20
21impl RecordingCommandBuffer<'_> {
25 pub unsafe fn set_blend_constants(&mut self, constants: &[f32; 4]) -> Result<&mut Self> {
27 Ok(unsafe { self.set_blend_constants_unchecked(constants) })
28 }
29
30 pub unsafe fn set_blend_constants_unchecked(&mut self, constants: &[f32; 4]) -> &mut Self {
31 let fns = self.device().fns();
32 unsafe { (fns.v1_0.cmd_set_blend_constants)(self.handle(), constants) };
33
34 self
35 }
36
37 pub unsafe fn set_color_write_enable(&mut self, enables: &[bool]) -> Result<&mut Self> {
39 Ok(unsafe { self.set_color_write_enable_unchecked(enables) })
40 }
41
42 pub unsafe fn set_color_write_enable_unchecked(&mut self, enables: &[bool]) -> &mut Self {
43 if enables.is_empty() {
44 return self;
45 }
46
47 let enables_vk = enables
48 .iter()
49 .copied()
50 .map(|v| v as vk::Bool32)
51 .collect::<SmallVec<[_; 4]>>();
52
53 let fns = self.device().fns();
54 unsafe {
55 (fns.ext_color_write_enable.cmd_set_color_write_enable_ext)(
56 self.handle(),
57 enables_vk.len() as u32,
58 enables_vk.as_ptr(),
59 )
60 };
61
62 self
63 }
64
65 pub unsafe fn set_cull_mode(&mut self, cull_mode: CullMode) -> Result<&mut Self> {
67 Ok(unsafe { self.set_cull_mode_unchecked(cull_mode) })
68 }
69
70 pub unsafe fn set_cull_mode_unchecked(&mut self, cull_mode: CullMode) -> &mut Self {
71 let fns = self.device().fns();
72 let cmd_set_cull_mode = if self.device().api_version() >= Version::V1_3 {
73 fns.v1_3.cmd_set_cull_mode
74 } else {
75 fns.ext_extended_dynamic_state.cmd_set_cull_mode_ext
76 };
77
78 unsafe { cmd_set_cull_mode(self.handle(), cull_mode.into()) };
79
80 self
81 }
82
83 pub unsafe fn set_depth_bias(
85 &mut self,
86 constant_factor: f32,
87 clamp: f32,
88 slope_factor: f32,
89 ) -> Result<&mut Self> {
90 Ok(unsafe { self.set_depth_bias_unchecked(constant_factor, clamp, slope_factor) })
91 }
92
93 pub unsafe fn set_depth_bias_unchecked(
94 &mut self,
95 constant_factor: f32,
96 clamp: f32,
97 slope_factor: f32,
98 ) -> &mut Self {
99 let fns = self.device().fns();
100 unsafe {
101 (fns.v1_0.cmd_set_depth_bias)(self.handle(), constant_factor, clamp, slope_factor)
102 };
103
104 self
105 }
106
107 pub unsafe fn set_depth_bias_enable(&mut self, enable: bool) -> Result<&mut Self> {
109 Ok(unsafe { self.set_depth_bias_enable_unchecked(enable) })
110 }
111
112 pub unsafe fn set_depth_bias_enable_unchecked(&mut self, enable: bool) -> &mut Self {
113 let fns = self.device().fns();
114 let cmd_set_depth_bias_enable = if self.device().api_version() >= Version::V1_3 {
115 fns.v1_3.cmd_set_depth_bias_enable
116 } else {
117 fns.ext_extended_dynamic_state2
118 .cmd_set_depth_bias_enable_ext
119 };
120
121 unsafe { cmd_set_depth_bias_enable(self.handle(), enable.into()) };
122
123 self
124 }
125
126 pub unsafe fn set_depth_bounds(&mut self, bounds: RangeInclusive<f32>) -> Result<&mut Self> {
128 Ok(unsafe { self.set_depth_bounds_unchecked(bounds.clone()) })
129 }
130
131 pub unsafe fn set_depth_bounds_unchecked(&mut self, bounds: RangeInclusive<f32>) -> &mut Self {
132 let fns = self.device().fns();
133 unsafe { (fns.v1_0.cmd_set_depth_bounds)(self.handle(), *bounds.start(), *bounds.end()) };
134
135 self
136 }
137
138 pub unsafe fn set_depth_bounds_test_enable(&mut self, enable: bool) -> Result<&mut Self> {
140 Ok(unsafe { self.set_depth_bounds_test_enable_unchecked(enable) })
141 }
142
143 pub unsafe fn set_depth_bounds_test_enable_unchecked(&mut self, enable: bool) -> &mut Self {
144 let fns = self.device().fns();
145 let cmd_set_depth_bounds_test_enable = if self.device().api_version() >= Version::V1_3 {
146 fns.v1_3.cmd_set_depth_bounds_test_enable
147 } else {
148 fns.ext_extended_dynamic_state
149 .cmd_set_depth_bounds_test_enable_ext
150 };
151
152 unsafe { cmd_set_depth_bounds_test_enable(self.handle(), enable.into()) };
153
154 self
155 }
156
157 pub unsafe fn set_depth_compare_op(&mut self, compare_op: CompareOp) -> Result<&mut Self> {
159 Ok(unsafe { self.set_depth_compare_op_unchecked(compare_op) })
160 }
161
162 pub unsafe fn set_depth_compare_op_unchecked(&mut self, compare_op: CompareOp) -> &mut Self {
163 let fns = self.device().fns();
164 let cmd_set_depth_compare_op = if self.device().api_version() >= Version::V1_3 {
165 fns.v1_3.cmd_set_depth_compare_op
166 } else {
167 fns.ext_extended_dynamic_state.cmd_set_depth_compare_op_ext
168 };
169
170 unsafe { cmd_set_depth_compare_op(self.handle(), compare_op.into()) };
171
172 self
173 }
174
175 pub unsafe fn set_depth_test_enable(&mut self, enable: bool) -> Result<&mut Self> {
177 Ok(unsafe { self.set_depth_test_enable_unchecked(enable) })
178 }
179
180 pub unsafe fn set_depth_test_enable_unchecked(&mut self, enable: bool) -> &mut Self {
181 let fns = self.device().fns();
182 let cmd_set_depth_test_enable = if self.device().api_version() >= Version::V1_3 {
183 fns.v1_3.cmd_set_depth_test_enable
184 } else {
185 fns.ext_extended_dynamic_state.cmd_set_depth_test_enable_ext
186 };
187
188 unsafe { cmd_set_depth_test_enable(self.handle(), enable.into()) };
189
190 self
191 }
192
193 pub unsafe fn set_depth_write_enable(&mut self, enable: bool) -> Result<&mut Self> {
195 Ok(unsafe { self.set_depth_write_enable_unchecked(enable) })
196 }
197
198 pub unsafe fn set_depth_write_enable_unchecked(&mut self, enable: bool) -> &mut Self {
199 let fns = self.device().fns();
200 let cmd_set_depth_write_enable = if self.device().api_version() >= Version::V1_3 {
201 fns.v1_3.cmd_set_depth_write_enable
202 } else {
203 fns.ext_extended_dynamic_state
204 .cmd_set_depth_write_enable_ext
205 };
206
207 unsafe { cmd_set_depth_write_enable(self.handle(), enable.into()) };
208
209 self
210 }
211
212 pub unsafe fn set_discard_rectangle(
214 &mut self,
215 first_rectangle: u32,
216 rectangles: &[Scissor],
217 ) -> Result<&mut Self> {
218 Ok(unsafe { self.set_discard_rectangle_unchecked(first_rectangle, rectangles) })
219 }
220
221 pub unsafe fn set_discard_rectangle_unchecked(
222 &mut self,
223 first_rectangle: u32,
224 rectangles: &[Scissor],
225 ) -> &mut Self {
226 if rectangles.is_empty() {
227 return self;
228 }
229
230 let rectangles_vk = rectangles
231 .iter()
232 .map(Scissor::to_vk)
233 .collect::<SmallVec<[_; 2]>>();
234
235 let fns = self.device().fns();
236 unsafe {
237 (fns.ext_discard_rectangles.cmd_set_discard_rectangle_ext)(
238 self.handle(),
239 first_rectangle,
240 rectangles_vk.len() as u32,
241 rectangles_vk.as_ptr(),
242 )
243 };
244
245 self
246 }
247
248 pub unsafe fn set_front_face(&mut self, face: FrontFace) -> Result<&mut Self> {
250 Ok(unsafe { self.set_front_face_unchecked(face) })
251 }
252
253 pub unsafe fn set_front_face_unchecked(&mut self, face: FrontFace) -> &mut Self {
254 let fns = self.device().fns();
255 let cmd_set_front_face = if self.device().api_version() >= Version::V1_3 {
256 fns.v1_3.cmd_set_front_face
257 } else {
258 fns.ext_extended_dynamic_state.cmd_set_front_face_ext
259 };
260
261 unsafe { cmd_set_front_face(self.handle(), face.into()) };
262
263 self
264 }
265
266 pub unsafe fn set_line_stipple(&mut self, factor: u32, pattern: u16) -> Result<&mut Self> {
268 Ok(unsafe { self.set_line_stipple_unchecked(factor, pattern) })
269 }
270
271 pub unsafe fn set_line_stipple_unchecked(&mut self, factor: u32, pattern: u16) -> &mut Self {
272 let fns = self.device().fns();
273 unsafe {
274 (fns.ext_line_rasterization.cmd_set_line_stipple_ext)(self.handle(), factor, pattern)
275 };
276
277 self
278 }
279
280 pub unsafe fn set_line_width(&mut self, line_width: f32) -> Result<&mut Self> {
282 Ok(unsafe { self.set_line_width_unchecked(line_width) })
283 }
284
285 pub unsafe fn set_line_width_unchecked(&mut self, line_width: f32) -> &mut Self {
286 let fns = self.device().fns();
287 unsafe { (fns.v1_0.cmd_set_line_width)(self.handle(), line_width) };
288
289 self
290 }
291
292 pub unsafe fn set_logic_op(&mut self, logic_op: LogicOp) -> Result<&mut Self> {
294 Ok(unsafe { self.set_logic_op_unchecked(logic_op) })
295 }
296
297 pub unsafe fn set_logic_op_unchecked(&mut self, logic_op: LogicOp) -> &mut Self {
298 let fns = self.device().fns();
299 unsafe {
300 (fns.ext_extended_dynamic_state2.cmd_set_logic_op_ext)(self.handle(), logic_op.into())
301 };
302
303 self
304 }
305
306 pub unsafe fn set_patch_control_points(&mut self, num: u32) -> Result<&mut Self> {
308 Ok(unsafe { self.set_patch_control_points_unchecked(num) })
309 }
310
311 pub unsafe fn set_patch_control_points_unchecked(&mut self, num: u32) -> &mut Self {
312 let fns = self.device().fns();
313 unsafe {
314 (fns.ext_extended_dynamic_state2
315 .cmd_set_patch_control_points_ext)(self.handle(), num)
316 };
317
318 self
319 }
320
321 pub unsafe fn set_primitive_restart_enable(&mut self, enable: bool) -> Result<&mut Self> {
323 Ok(unsafe { self.set_primitive_restart_enable_unchecked(enable) })
324 }
325
326 pub unsafe fn set_primitive_restart_enable_unchecked(&mut self, enable: bool) -> &mut Self {
327 let fns = self.device().fns();
328 let cmd_set_primitive_restart_enable = if self.device().api_version() >= Version::V1_3 {
329 fns.v1_3.cmd_set_primitive_restart_enable
330 } else {
331 fns.ext_extended_dynamic_state2
332 .cmd_set_primitive_restart_enable_ext
333 };
334
335 unsafe { cmd_set_primitive_restart_enable(self.handle(), enable.into()) };
336
337 self
338 }
339
340 pub unsafe fn set_primitive_topology(
342 &mut self,
343 topology: PrimitiveTopology,
344 ) -> Result<&mut Self> {
345 Ok(unsafe { self.set_primitive_topology_unchecked(topology) })
346 }
347
348 pub unsafe fn set_primitive_topology_unchecked(
349 &mut self,
350 topology: PrimitiveTopology,
351 ) -> &mut Self {
352 let fns = self.device().fns();
353 let cmd_set_primitive_topology = if self.device().api_version() >= Version::V1_3 {
354 fns.v1_3.cmd_set_primitive_topology
355 } else {
356 fns.ext_extended_dynamic_state
357 .cmd_set_primitive_topology_ext
358 };
359
360 unsafe { cmd_set_primitive_topology(self.handle(), topology.into()) };
361
362 self
363 }
364
365 pub unsafe fn set_rasterizer_discard_enable(&mut self, enable: bool) -> Result<&mut Self> {
367 Ok(unsafe { self.set_rasterizer_discard_enable_unchecked(enable) })
368 }
369
370 pub unsafe fn set_rasterizer_discard_enable_unchecked(&mut self, enable: bool) -> &mut Self {
371 let fns = self.device().fns();
372 let cmd_set_rasterizer_discard_enable = if self.device().api_version() >= Version::V1_3 {
373 fns.v1_3.cmd_set_rasterizer_discard_enable
374 } else {
375 fns.ext_extended_dynamic_state2
376 .cmd_set_rasterizer_discard_enable_ext
377 };
378
379 unsafe { cmd_set_rasterizer_discard_enable(self.handle(), enable.into()) };
380
381 self
382 }
383
384 pub unsafe fn set_scissor(
386 &mut self,
387 first_scissor: u32,
388 scissors: &[Scissor],
389 ) -> Result<&mut Self> {
390 Ok(unsafe { self.set_scissor_unchecked(first_scissor, scissors) })
391 }
392
393 pub unsafe fn set_scissor_unchecked(
394 &mut self,
395 first_scissor: u32,
396 scissors: &[Scissor],
397 ) -> &mut Self {
398 if scissors.is_empty() {
399 return self;
400 }
401
402 let scissors_vk = scissors
403 .iter()
404 .map(Scissor::to_vk)
405 .collect::<SmallVec<[_; 2]>>();
406
407 let fns = self.device().fns();
408 unsafe {
409 (fns.v1_0.cmd_set_scissor)(
410 self.handle(),
411 first_scissor,
412 scissors_vk.len() as u32,
413 scissors_vk.as_ptr(),
414 )
415 };
416
417 self
418 }
419
420 pub unsafe fn set_scissor_with_count(&mut self, scissors: &[Scissor]) -> Result<&mut Self> {
422 Ok(unsafe { self.set_scissor_with_count_unchecked(scissors) })
423 }
424
425 pub unsafe fn set_scissor_with_count_unchecked(&mut self, scissors: &[Scissor]) -> &mut Self {
426 if scissors.is_empty() {
427 return self;
428 }
429
430 let scissors_vk = scissors
431 .iter()
432 .map(Scissor::to_vk)
433 .collect::<SmallVec<[_; 2]>>();
434
435 let fns = self.device().fns();
436 let cmd_set_scissor_with_count = if self.device().api_version() >= Version::V1_3 {
437 fns.v1_3.cmd_set_scissor_with_count
438 } else {
439 fns.ext_extended_dynamic_state
440 .cmd_set_scissor_with_count_ext
441 };
442
443 unsafe {
444 cmd_set_scissor_with_count(
445 self.handle(),
446 scissors_vk.len() as u32,
447 scissors_vk.as_ptr(),
448 )
449 };
450
451 self
452 }
453
454 pub unsafe fn set_stencil_compare_mask(
456 &mut self,
457 faces: StencilFaces,
458 compare_mask: u32,
459 ) -> Result<&mut Self> {
460 Ok(unsafe { self.set_stencil_compare_mask_unchecked(faces, compare_mask) })
461 }
462
463 pub unsafe fn set_stencil_compare_mask_unchecked(
464 &mut self,
465 faces: StencilFaces,
466 compare_mask: u32,
467 ) -> &mut Self {
468 let fns = self.device().fns();
469 unsafe {
470 (fns.v1_0.cmd_set_stencil_compare_mask)(self.handle(), faces.into(), compare_mask)
471 };
472
473 self
474 }
475
476 pub unsafe fn set_stencil_op(
478 &mut self,
479 faces: StencilFaces,
480 fail_op: StencilOp,
481 pass_op: StencilOp,
482 depth_fail_op: StencilOp,
483 compare_op: CompareOp,
484 ) -> Result<&mut Self> {
485 Ok(unsafe {
486 self.set_stencil_op_unchecked(faces, fail_op, pass_op, depth_fail_op, compare_op)
487 })
488 }
489
490 pub unsafe fn set_stencil_op_unchecked(
491 &mut self,
492 faces: StencilFaces,
493 fail_op: StencilOp,
494 pass_op: StencilOp,
495 depth_fail_op: StencilOp,
496 compare_op: CompareOp,
497 ) -> &mut Self {
498 let fns = self.device().fns();
499 let cmd_set_stencil_op = if self.device().api_version() >= Version::V1_3 {
500 fns.v1_3.cmd_set_stencil_op
501 } else {
502 fns.ext_extended_dynamic_state.cmd_set_stencil_op_ext
503 };
504
505 unsafe {
506 cmd_set_stencil_op(
507 self.handle(),
508 faces.into(),
509 fail_op.into(),
510 pass_op.into(),
511 depth_fail_op.into(),
512 compare_op.into(),
513 )
514 };
515
516 self
517 }
518
519 pub unsafe fn set_stencil_reference(
521 &mut self,
522 faces: StencilFaces,
523 reference: u32,
524 ) -> Result<&mut Self> {
525 Ok(unsafe { self.set_stencil_reference_unchecked(faces, reference) })
526 }
527
528 pub unsafe fn set_stencil_reference_unchecked(
529 &mut self,
530 faces: StencilFaces,
531 reference: u32,
532 ) -> &mut Self {
533 let fns = self.device().fns();
534 unsafe { (fns.v1_0.cmd_set_stencil_reference)(self.handle(), faces.into(), reference) };
535
536 self
537 }
538
539 pub unsafe fn set_stencil_test_enable(&mut self, enable: bool) -> Result<&mut Self> {
541 Ok(unsafe { self.set_stencil_test_enable_unchecked(enable) })
542 }
543
544 pub unsafe fn set_stencil_test_enable_unchecked(&mut self, enable: bool) -> &mut Self {
545 let fns = self.device().fns();
546 let cmd_set_stencil_test_enable = if self.device().api_version() >= Version::V1_3 {
547 fns.v1_3.cmd_set_stencil_test_enable
548 } else {
549 fns.ext_extended_dynamic_state
550 .cmd_set_stencil_test_enable_ext
551 };
552
553 unsafe { cmd_set_stencil_test_enable(self.handle(), enable.into()) };
554
555 self
556 }
557
558 pub unsafe fn set_stencil_write_mask(
560 &mut self,
561 faces: StencilFaces,
562 write_mask: u32,
563 ) -> Result<&mut Self> {
564 Ok(unsafe { self.set_stencil_write_mask_unchecked(faces, write_mask) })
565 }
566
567 pub unsafe fn set_stencil_write_mask_unchecked(
568 &mut self,
569 faces: StencilFaces,
570 write_mask: u32,
571 ) -> &mut Self {
572 let fns = self.device().fns();
573 unsafe { (fns.v1_0.cmd_set_stencil_write_mask)(self.handle(), faces.into(), write_mask) };
574
575 self
576 }
577
578 pub unsafe fn set_vertex_input(
580 &mut self,
581 vertex_input_state: &VertexInputState,
582 ) -> Result<&mut Self> {
583 Ok(unsafe { self.set_vertex_input_unchecked(vertex_input_state) })
584 }
585
586 pub unsafe fn set_vertex_input_unchecked(
587 &mut self,
588 vertex_input_state: &VertexInputState,
589 ) -> &mut Self {
590 let mut vertex_binding_descriptions_vk: SmallVec<[_; 8]> = SmallVec::new();
591 let mut vertex_attribute_descriptions_vk: SmallVec<[_; 8]> = SmallVec::new();
592
593 let VertexInputState {
594 bindings,
595 attributes,
596 _ne: _,
597 } = vertex_input_state;
598
599 vertex_binding_descriptions_vk.extend(bindings.iter().map(|(&binding, binding_desc)| {
600 let &VertexInputBindingDescription {
601 stride,
602 input_rate,
603 _ne: _,
604 } = binding_desc;
605
606 let (input_rate, divisor) = input_rate.to_vk();
607
608 vk::VertexInputBindingDescription2EXT {
609 binding,
610 stride,
611 input_rate,
612 divisor,
613 ..Default::default()
614 }
615 }));
616
617 vertex_attribute_descriptions_vk.extend(attributes.iter().map(
618 |(&location, attribute_desc)| {
619 let &VertexInputAttributeDescription {
620 binding,
621 format,
622 offset,
623 _ne: _,
624 } = attribute_desc;
625
626 vk::VertexInputAttributeDescription2EXT {
627 location,
628 binding,
629 format: format.into(),
630 offset,
631 ..Default::default()
632 }
633 },
634 ));
635
636 let fns = self.device().fns();
637 unsafe {
638 (fns.ext_vertex_input_dynamic_state.cmd_set_vertex_input_ext)(
639 self.handle(),
640 vertex_binding_descriptions_vk.len() as u32,
641 vertex_binding_descriptions_vk.as_ptr(),
642 vertex_attribute_descriptions_vk.len() as u32,
643 vertex_attribute_descriptions_vk.as_ptr(),
644 )
645 };
646
647 self
648 }
649
650 pub unsafe fn set_viewport(
652 &mut self,
653 first_viewport: u32,
654 viewports: &[Viewport],
655 ) -> Result<&mut Self> {
656 Ok(unsafe { self.set_viewport_unchecked(first_viewport, viewports) })
657 }
658
659 pub unsafe fn set_viewport_unchecked(
660 &mut self,
661 first_viewport: u32,
662 viewports: &[Viewport],
663 ) -> &mut Self {
664 if viewports.is_empty() {
665 return self;
666 }
667
668 let viewports_vk = viewports
669 .iter()
670 .map(Viewport::to_vk)
671 .collect::<SmallVec<[_; 2]>>();
672
673 let fns = self.device().fns();
674 unsafe {
675 (fns.v1_0.cmd_set_viewport)(
676 self.handle(),
677 first_viewport,
678 viewports_vk.len() as u32,
679 viewports_vk.as_ptr(),
680 )
681 };
682
683 self
684 }
685
686 pub unsafe fn set_viewport_with_count(&mut self, viewports: &[Viewport]) -> Result<&mut Self> {
688 Ok(unsafe { self.set_viewport_with_count_unchecked(viewports) })
689 }
690
691 pub unsafe fn set_viewport_with_count_unchecked(
692 &mut self,
693 viewports: &[Viewport],
694 ) -> &mut Self {
695 if viewports.is_empty() {
696 return self;
697 }
698
699 let viewports_vk = viewports
700 .iter()
701 .map(Viewport::to_vk)
702 .collect::<SmallVec<[_; 2]>>();
703
704 let fns = self.device().fns();
705 let cmd_set_viewport_with_count = if self.device().api_version() >= Version::V1_3 {
706 fns.v1_3.cmd_set_viewport_with_count
707 } else {
708 fns.ext_extended_dynamic_state
709 .cmd_set_viewport_with_count_ext
710 };
711
712 unsafe {
713 cmd_set_viewport_with_count(
714 self.handle(),
715 viewports_vk.len() as u32,
716 viewports_vk.as_ptr(),
717 )
718 };
719
720 self
721 }
722
723 pub unsafe fn set_conservative_rasterization_mode(
725 &mut self,
726 conservative_rasterization_mode: ConservativeRasterizationMode,
727 ) -> Result<&mut Self> {
728 Ok(unsafe {
729 self.set_conservative_rasterization_mode_unchecked(conservative_rasterization_mode)
730 })
731 }
732
733 pub unsafe fn set_conservative_rasterization_mode_unchecked(
734 &mut self,
735 conservative_rasterization_mode: ConservativeRasterizationMode,
736 ) -> &mut Self {
737 let fns = self.device().fns();
738 unsafe {
739 (fns.ext_extended_dynamic_state3
740 .cmd_set_conservative_rasterization_mode_ext)(
741 self.handle(),
742 conservative_rasterization_mode.into(),
743 )
744 };
745
746 self
747 }
748
749 pub unsafe fn set_extra_primitive_overestimation_size(
751 &mut self,
752 extra_primitive_overestimation_size: f32,
753 ) -> Result<&mut Self> {
754 Ok(unsafe {
755 self.set_extra_primitive_overestimation_size_unchecked(
756 extra_primitive_overestimation_size,
757 )
758 })
759 }
760
761 pub unsafe fn set_extra_primitive_overestimation_size_unchecked(
762 &mut self,
763 extra_primitive_overestimation_size: f32,
764 ) -> &mut Self {
765 let fns = self.device().fns();
766 unsafe {
767 (fns.ext_extended_dynamic_state3
768 .cmd_set_extra_primitive_overestimation_size_ext)(
769 self.handle(),
770 extra_primitive_overestimation_size,
771 )
772 };
773
774 self
775 }
776
777 pub unsafe fn set_fragment_shading_rate(
779 &mut self,
780 fragment_size: [u32; 2],
781 combiner_ops: [FragmentShadingRateCombinerOp; 2],
782 ) -> Result<&mut Self> {
783 Ok(unsafe { self.set_fragment_shading_rate_unchecked(fragment_size, combiner_ops) })
784 }
785
786 pub unsafe fn set_fragment_shading_rate_unchecked(
787 &mut self,
788 fragment_size: [u32; 2],
789 combiner_ops: [FragmentShadingRateCombinerOp; 2],
790 ) -> &mut Self {
791 let fns = self.device().fns();
792 let fragment_size = vk::Extent2D {
793 width: fragment_size[0],
794 height: fragment_size[1],
795 };
796 let combiner_ops = [combiner_ops[0].into(), combiner_ops[1].into()];
797 unsafe {
798 (fns.khr_fragment_shading_rate
799 .cmd_set_fragment_shading_rate_khr)(
800 self.handle(), &fragment_size, &combiner_ops
801 )
802 }
803
804 self
805 }
806}