]> git.nega.tv - josh/narcissus/commitdiff
narcissus-gpu: Add push constants to pipeline layout
authorJosh Simmons <josh@nega.tv>
Sat, 25 May 2024 13:41:30 +0000 (15:41 +0200)
committerJosh Simmons <josh@nega.tv>
Sat, 25 May 2024 13:41:30 +0000 (15:41 +0200)
engine/narcissus-gpu/src/backend/vulkan/convert.rs
engine/narcissus-gpu/src/backend/vulkan/mod.rs
engine/narcissus-gpu/src/lib.rs
title/shark/src/pipelines/basic.rs
title/shark/src/pipelines/display_transform.rs
title/shark/src/pipelines/primitive_2d.rs

index e94f74766792f0fe3515d80b6042c105bdae6404..3813cbe39aaf9adb3fca325ce598b0fb165a690c 100644 (file)
@@ -7,7 +7,7 @@ use crate::{
     BindingType, BlendMode, BufferUsageFlags, ClearValue, ColorSpace, CompareOp, CullingMode,
     FrontFace, ImageAspectFlags, ImageDimension, ImageFormat, ImageSubresourceLayers,
     ImageSubresourceRange, ImageTiling, ImageUsageFlags, IndexType, LoadOp, PolygonMode,
-    PresentMode, ShaderStageFlags, StencilOp, StencilOpState, StoreOp, Topology,
+    PresentMode, PushConstantRange, ShaderStageFlags, StencilOp, StencilOpState, StoreOp, Topology,
 };
 
 #[must_use]
@@ -190,6 +190,15 @@ pub fn vulkan_shader_stage_flags(stage_flags: ShaderStageFlags) -> vk::ShaderSta
     flags
 }
 
+#[must_use]
+pub fn vulkan_push_constant_range(push_constant_range: PushConstantRange) -> vk::PushConstantRange {
+    vk::PushConstantRange {
+        stage_flags: vulkan_shader_stage_flags(push_constant_range.stage_flags),
+        offset: push_constant_range.offset,
+        size: push_constant_range.size,
+    }
+}
+
 #[must_use]
 pub fn vulkan_descriptor_type(binding_type: BindingType) -> vk::DescriptorType {
     match binding_type {
index c5ec0d002c0474d5cef379840070b525c853a18a..4b89dc6c56cc83f1ab34b48585087e9957c3601a 100644 (file)
@@ -2692,6 +2692,19 @@ impl VulkanDevice {
                         .as_bytes(),
                 );
             }
+            for push_constant_range in pipeline_layout.push_constant_ranges {
+                assert!(
+                    push_constant_range.offset & 3 == 0,
+                    "push constant offsets must be 4 byte aligned"
+                );
+                assert!(
+                    push_constant_range.size & 3 == 0,
+                    "push constant sizes must be 4 byte aligned"
+                );
+                hasher.update(&push_constant_range.stage_flags.as_raw().to_le_bytes());
+                hasher.update(&push_constant_range.offset.to_le_bytes());
+                hasher.update(&push_constant_range.size.to_le_bytes());
+            }
             hasher.finalize()
         };
 
@@ -2718,9 +2731,18 @@ impl VulkanDevice {
                             });
                     let set_layouts = arena.alloc_slice_fill_iter(set_layouts_iter);
 
+                    let push_constant_ranges_iter = pipeline_layout
+                        .push_constant_ranges
+                        .iter()
+                        .copied()
+                        .map(vulkan_push_constant_range);
+                    let push_constant_ranges =
+                        arena.alloc_slice_fill_iter(push_constant_ranges_iter);
+
                     let pipeline_layout = {
                         let create_info = vk::PipelineLayoutCreateInfo {
                             set_layouts: set_layouts.into(),
+                            push_constant_ranges: push_constant_ranges.into(),
                             ..default()
                         };
                         let mut pipeline_layout = vk::PipelineLayout::null();
index c44aaac1cfede3b2b9e82820f83b0e8a05c2c156..26447b1f5de7d107382e877fc740f1312cad078c 100644 (file)
@@ -394,9 +394,17 @@ pub struct DepthBias {
     pub slope_factor: f32,
 }
 
+#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+pub struct PushConstantRange {
+    pub stage_flags: ShaderStageFlags,
+    pub offset: u32,
+    pub size: u32,
+}
+
 #[derive(PartialEq, Eq, Hash)]
 pub struct PipelineLayout<'a> {
     pub bind_group_layouts: &'a [BindGroupLayout],
+    pub push_constant_ranges: &'a [PushConstantRange],
 }
 
 pub struct GraphicsPipelineAttachments<'a> {
index 1fa174a285c5294cdd2c786ecf7dffd74f6ccdf9..ffb67238ee415c20978682d2adee40b9653d4ca9 100644 (file)
@@ -48,6 +48,7 @@ impl BasicPipeline {
 
         let layout = &PipelineLayout {
             bind_group_layouts: &[uniforms_bind_group_layout, storage_bind_group_layout],
+            push_constant_ranges: &[],
         };
 
         let pipeline = gpu.create_graphics_pipeline(&GraphicsPipelineDesc {
index 9ba4ec9152f5578fd74fcfb4c4c1c358827ec056..0133787ac4f37cb6d0d71eefa029508b7bcc14a9 100644 (file)
@@ -27,6 +27,7 @@ impl DisplayTransformPipeline {
 
         let layout = &PipelineLayout {
             bind_group_layouts: &[bind_group_layout],
+            push_constant_ranges: &[],
         };
 
         let pipeline = gpu.create_compute_pipeline(&ComputePipelineDesc {
index 01cc83363863fbdf9b2998ad3e7de21939d907ea..2af7742dca9403de3298d84230584a74bf155b55 100644 (file)
@@ -74,6 +74,7 @@ impl Primitive2dPipeline {
 
         let layout = &PipelineLayout {
             bind_group_layouts: &[bind_group_layout],
+            push_constant_ranges: &[],
         };
 
         let coarse_bin_pipeline = gpu.create_compute_pipeline(&ComputePipelineDesc {