typed primitive buffers + macro for creation

This commit is contained in:
2025-08-21 19:37:50 -04:00
parent b7f83b58a9
commit bde929b05a
5 changed files with 190 additions and 105 deletions

View File

@@ -1,6 +1,6 @@
use crate::{
primitive::{PrimitiveInstance, Primitives},
render::util::ArrBuf,
primitive::{PrimitiveBuffers, Primitives},
render::{data::PrimitiveInstance, util::ArrBuf},
};
use data::WindowUniform;
use wgpu::{
@@ -16,40 +16,34 @@ mod util;
const SHAPE_SHADER: &str = include_str!("./shader.wgsl");
pub struct UIRenderNode {
bind_group_layout: BindGroupLayout,
bind_group: BindGroup,
layout0: BindGroupLayout,
group0: BindGroup,
primitive_layout: BindGroupLayout,
primitive_group: BindGroup,
pipeline: RenderPipeline,
window_buffer: Buffer,
instance: ArrBuf<PrimitiveInstance>,
data: ArrBuf<u32>,
primitives: PrimitiveBuffers,
}
impl UIRenderNode {
pub fn draw<'a>(&'a self, pass: &mut RenderPass<'a>) {
pass.set_pipeline(&self.pipeline);
pass.set_bind_group(0, &self.bind_group, &[]);
if self.instance.len() != 0 {
pass.set_pipeline(&self.pipeline);
pass.set_bind_group(0, &self.group0, &[]);
pass.set_bind_group(1, &self.primitive_group, &[]);
pass.set_vertex_buffer(0, self.instance.buffer.slice(..));
pass.draw(0..4, 0..self.instance.len() as u32);
}
}
pub fn update(
&mut self,
device: &Device,
queue: &Queue,
primitives: Option<&Primitives>,
) {
pub fn update(&mut self, device: &Device, queue: &Queue, primitives: Option<&Primitives>) {
if let Some(primitives) = primitives {
self.instance.update(device, queue, &primitives.instances);
self.data.update(device, queue, &primitives.data);
self.bind_group = Self::bind_group(
device,
&self.bind_group_layout,
&self.window_buffer,
&self.data.buffer,
)
self.primitives.update(device, queue, &primitives.data);
self.primitive_group =
Self::primitive_group(device, &self.primitive_layout, self.primitives.buffers())
}
}
@@ -69,7 +63,7 @@ impl UIRenderNode {
let window_uniform = WindowUniform::default();
let window_buffer = device.create_buffer_init(&BufferInitDescriptor {
label: Some("Camera Buffer"),
label: Some("window"),
contents: bytemuck::cast_slice(&[window_uniform]),
usage: BufferUsages::UNIFORM | BufferUsages::COPY_DST,
});
@@ -79,26 +73,28 @@ impl UIRenderNode {
BufferUsages::VERTEX | BufferUsages::COPY_DST,
"instance",
);
let data = ArrBuf::new(
device,
BufferUsages::STORAGE | BufferUsages::COPY_DST,
"data",
);
let primitives = PrimitiveBuffers::new(device);
let bind_group_layout = device.create_bind_group_layout(&BindGroupLayoutDescriptor {
entries: &[
BindGroupLayoutEntry {
binding: 0,
visibility: ShaderStages::VERTEX,
ty: BindingType::Buffer {
ty: BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: None,
},
count: None,
let layout0 = device.create_bind_group_layout(&BindGroupLayoutDescriptor {
entries: &[BindGroupLayoutEntry {
binding: 0,
visibility: ShaderStages::VERTEX,
ty: BindingType::Buffer {
ty: BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: None,
},
count: None,
}],
label: Some("window"),
});
let group0 = Self::bind_group_0(device, &layout0, &window_buffer);
let primitive_layout = device.create_bind_group_layout(&BindGroupLayoutDescriptor {
entries: &core::array::from_fn::<_, { PrimitiveBuffers::LEN }, _>(|i| {
BindGroupLayoutEntry {
binding: 1,
binding: i as u32,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Buffer {
ty: BufferBindingType::Storage { read_only: true },
@@ -106,16 +102,17 @@ impl UIRenderNode {
min_binding_size: None,
},
count: None,
},
],
label: Some("camera_bind_group_layout"),
}
}),
label: Some("primitive"),
});
let bind_group = Self::bind_group(device, &bind_group_layout, &window_buffer, &data.buffer);
let primitive_group =
Self::primitive_group(device, &primitive_layout, primitives.buffers());
let pipeline_layout = device.create_pipeline_layout(&PipelineLayoutDescriptor {
label: Some("UI Shape Pipeline Layout"),
bind_group_layouts: &[&bind_group_layout],
bind_group_layouts: &[&layout0, &primitive_layout],
push_constant_ranges: &[],
});
let pipeline = device.create_render_pipeline(&RenderPipelineDescriptor {
@@ -157,34 +154,44 @@ impl UIRenderNode {
});
Self {
bind_group_layout,
bind_group,
layout0,
group0,
primitive_layout,
primitive_group,
pipeline,
window_buffer,
instance,
data,
primitives,
}
}
pub fn bind_group(
pub fn bind_group_0(
device: &Device,
layout: &BindGroupLayout,
window_buffer: &Buffer,
data: &Buffer,
) -> BindGroup {
device.create_bind_group(&BindGroupDescriptor {
layout,
entries: &[
BindGroupEntry {
binding: 0,
resource: window_buffer.as_entire_binding(),
},
BindGroupEntry {
binding: 1,
resource: data.as_entire_binding(),
},
],
label: Some("ui_bind_group"),
entries: &[BindGroupEntry {
binding: 0,
resource: window_buffer.as_entire_binding(),
}],
label: Some("ui window"),
})
}
pub fn primitive_group(
device: &Device,
layout: &BindGroupLayout,
buffers: [&Buffer; PrimitiveBuffers::LEN],
) -> BindGroup {
device.create_bind_group(&BindGroupDescriptor {
layout,
entries: &buffers.each_ref().map(|b| BindGroupEntry {
binding: 0,
resource: b.as_entire_binding(),
}),
label: Some("ui primitives"),
})
}
}