1use crate::gpu::buffer::{GradientUniforms, GradientVertex, TexVertex, Vertex};
29use crate::gpu::device::TARGET_FORMAT;
30
31pub struct SolidPipeline {
36 pub pipeline: wgpu::RenderPipeline,
38 pub globals_layout: wgpu::BindGroupLayout,
40}
41
42impl SolidPipeline {
43 pub fn new(device: &wgpu::Device, sample_count: u32) -> Self {
48 let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
49 label: Some("oxiui-render-wgpu solid.wgsl"),
50 source: wgpu::ShaderSource::Wgsl(include_str!("../shaders/solid.wgsl").into()),
51 });
52
53 let globals_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
54 label: Some("oxiui-render-wgpu globals layout"),
55 entries: &[wgpu::BindGroupLayoutEntry {
56 binding: 0,
57 visibility: wgpu::ShaderStages::VERTEX,
58 ty: wgpu::BindingType::Buffer {
59 ty: wgpu::BufferBindingType::Uniform,
60 has_dynamic_offset: false,
61 min_binding_size: None,
62 },
63 count: None,
64 }],
65 });
66
67 let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
68 label: Some("oxiui-render-wgpu solid pipeline layout"),
69 bind_group_layouts: &[Some(&globals_layout)],
70 immediate_size: 0,
71 });
72
73 let attrs = [
82 wgpu::VertexAttribute {
83 format: wgpu::VertexFormat::Float32x2,
84 offset: 0,
85 shader_location: 0,
86 },
87 wgpu::VertexAttribute {
88 format: wgpu::VertexFormat::Float32x4,
89 offset: 8,
90 shader_location: 1,
91 },
92 wgpu::VertexAttribute {
93 format: wgpu::VertexFormat::Float32x2,
94 offset: 24,
95 shader_location: 2,
96 },
97 wgpu::VertexAttribute {
98 format: wgpu::VertexFormat::Float32x2,
99 offset: 32,
100 shader_location: 3,
101 },
102 wgpu::VertexAttribute {
103 format: wgpu::VertexFormat::Float32,
104 offset: 40,
105 shader_location: 4,
106 },
107 wgpu::VertexAttribute {
108 format: wgpu::VertexFormat::Float32,
109 offset: 44,
110 shader_location: 5,
111 },
112 wgpu::VertexAttribute {
113 format: wgpu::VertexFormat::Float32x2,
114 offset: 48,
115 shader_location: 6,
116 },
117 ];
118
119 let vertex_layout = wgpu::VertexBufferLayout {
120 array_stride: core::mem::size_of::<Vertex>() as wgpu::BufferAddress,
121 step_mode: wgpu::VertexStepMode::Vertex,
122 attributes: &attrs,
123 };
124
125 let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
126 label: Some("oxiui-render-wgpu solid pipeline"),
127 layout: Some(&pipeline_layout),
128 vertex: wgpu::VertexState {
129 module: &shader,
130 entry_point: Some("vs_main"),
131 buffers: &[vertex_layout],
132 compilation_options: wgpu::PipelineCompilationOptions::default(),
133 },
134 fragment: Some(wgpu::FragmentState {
135 module: &shader,
136 entry_point: Some("fs_main"),
137 targets: &[Some(wgpu::ColorTargetState {
138 format: TARGET_FORMAT,
139 blend: Some(wgpu::BlendState::ALPHA_BLENDING),
140 write_mask: wgpu::ColorWrites::ALL,
141 })],
142 compilation_options: wgpu::PipelineCompilationOptions::default(),
143 }),
144 primitive: wgpu::PrimitiveState {
145 topology: wgpu::PrimitiveTopology::TriangleList,
146 strip_index_format: None,
147 front_face: wgpu::FrontFace::Ccw,
148 cull_mode: None,
149 unclipped_depth: false,
150 polygon_mode: wgpu::PolygonMode::Fill,
151 conservative: false,
152 },
153 depth_stencil: None,
154 multisample: wgpu::MultisampleState {
155 count: sample_count,
156 mask: !0,
157 alpha_to_coverage_enabled: false,
158 },
159 multiview_mask: None,
160 cache: None,
161 });
162
163 Self {
164 pipeline,
165 globals_layout,
166 }
167 }
168}
169
170pub struct GradientPipeline {
175 pub pipeline: wgpu::RenderPipeline,
177 pub bind_group_layout: wgpu::BindGroupLayout,
180}
181
182impl GradientPipeline {
183 pub fn new(device: &wgpu::Device, sample_count: u32) -> Self {
188 let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
189 label: Some("oxiui-render-wgpu gradient.wgsl"),
190 source: wgpu::ShaderSource::Wgsl(include_str!("../shaders/gradient.wgsl").into()),
191 });
192
193 let grad_uniform_size = core::mem::size_of::<GradientUniforms>() as u64;
202 let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
203 label: Some("oxiui-render-wgpu gradient bind group layout"),
204 entries: &[
205 wgpu::BindGroupLayoutEntry {
206 binding: 0,
207 visibility: wgpu::ShaderStages::VERTEX,
208 ty: wgpu::BindingType::Buffer {
209 ty: wgpu::BufferBindingType::Uniform,
210 has_dynamic_offset: false,
211 min_binding_size: None,
212 },
213 count: None,
214 },
215 wgpu::BindGroupLayoutEntry {
216 binding: 1,
217 visibility: wgpu::ShaderStages::FRAGMENT,
218 ty: wgpu::BindingType::Buffer {
219 ty: wgpu::BufferBindingType::Uniform,
220 has_dynamic_offset: true,
221 min_binding_size: core::num::NonZeroU64::new(grad_uniform_size),
222 },
223 count: None,
224 },
225 ],
226 });
227
228 let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
229 label: Some("oxiui-render-wgpu gradient pipeline layout"),
230 bind_group_layouts: &[Some(&bind_group_layout)],
231 immediate_size: 0,
232 });
233
234 let attrs = [
238 wgpu::VertexAttribute {
239 format: wgpu::VertexFormat::Float32x2,
240 offset: 0,
241 shader_location: 0,
242 },
243 wgpu::VertexAttribute {
244 format: wgpu::VertexFormat::Float32x2,
245 offset: 8,
246 shader_location: 1,
247 },
248 ];
249
250 let vertex_layout = wgpu::VertexBufferLayout {
251 array_stride: core::mem::size_of::<GradientVertex>() as wgpu::BufferAddress,
252 step_mode: wgpu::VertexStepMode::Vertex,
253 attributes: &attrs,
254 };
255
256 let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
257 label: Some("oxiui-render-wgpu gradient pipeline"),
258 layout: Some(&pipeline_layout),
259 vertex: wgpu::VertexState {
260 module: &shader,
261 entry_point: Some("vs_main"),
262 buffers: &[vertex_layout],
263 compilation_options: wgpu::PipelineCompilationOptions::default(),
264 },
265 fragment: Some(wgpu::FragmentState {
266 module: &shader,
267 entry_point: Some("fs_main"),
268 targets: &[Some(wgpu::ColorTargetState {
269 format: TARGET_FORMAT,
270 blend: Some(wgpu::BlendState::ALPHA_BLENDING),
271 write_mask: wgpu::ColorWrites::ALL,
272 })],
273 compilation_options: wgpu::PipelineCompilationOptions::default(),
274 }),
275 primitive: wgpu::PrimitiveState {
276 topology: wgpu::PrimitiveTopology::TriangleList,
277 strip_index_format: None,
278 front_face: wgpu::FrontFace::Ccw,
279 cull_mode: None,
280 unclipped_depth: false,
281 polygon_mode: wgpu::PolygonMode::Fill,
282 conservative: false,
283 },
284 depth_stencil: None,
285 multisample: wgpu::MultisampleState {
286 count: sample_count,
287 mask: !0,
288 alpha_to_coverage_enabled: false,
289 },
290 multiview_mask: None,
291 cache: None,
292 });
293
294 Self {
295 pipeline,
296 bind_group_layout,
297 }
298 }
299}
300
301pub struct TexturedPipeline {
311 pub pipeline: wgpu::RenderPipeline,
313 pub globals_layout: wgpu::BindGroupLayout,
315 pub texture_layout: wgpu::BindGroupLayout,
317}
318
319impl TexturedPipeline {
320 pub fn new(device: &wgpu::Device, sample_count: u32) -> Self {
325 let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
326 label: Some("oxiui-render-wgpu textured.wgsl"),
327 source: wgpu::ShaderSource::Wgsl(include_str!("../shaders/textured.wgsl").into()),
328 });
329
330 let globals_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
332 label: Some("oxiui-render-wgpu textured globals layout"),
333 entries: &[wgpu::BindGroupLayoutEntry {
334 binding: 0,
335 visibility: wgpu::ShaderStages::VERTEX,
336 ty: wgpu::BindingType::Buffer {
337 ty: wgpu::BufferBindingType::Uniform,
338 has_dynamic_offset: false,
339 min_binding_size: None,
340 },
341 count: None,
342 }],
343 });
344
345 let texture_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
347 label: Some("oxiui-render-wgpu textured texture layout"),
348 entries: &[
349 wgpu::BindGroupLayoutEntry {
350 binding: 0,
351 visibility: wgpu::ShaderStages::FRAGMENT,
352 ty: wgpu::BindingType::Texture {
353 sample_type: wgpu::TextureSampleType::Float { filterable: true },
354 view_dimension: wgpu::TextureViewDimension::D2,
355 multisampled: false,
356 },
357 count: None,
358 },
359 wgpu::BindGroupLayoutEntry {
360 binding: 1,
361 visibility: wgpu::ShaderStages::FRAGMENT,
362 ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
363 count: None,
364 },
365 ],
366 });
367
368 let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
369 label: Some("oxiui-render-wgpu textured pipeline layout"),
370 bind_group_layouts: &[Some(&globals_layout), Some(&texture_layout)],
371 immediate_size: 0,
372 });
373
374 let attrs = [
379 wgpu::VertexAttribute {
380 format: wgpu::VertexFormat::Float32x2,
381 offset: 0,
382 shader_location: 0,
383 },
384 wgpu::VertexAttribute {
385 format: wgpu::VertexFormat::Float32x2,
386 offset: 8,
387 shader_location: 1,
388 },
389 wgpu::VertexAttribute {
390 format: wgpu::VertexFormat::Float32x4,
391 offset: 16,
392 shader_location: 2,
393 },
394 ];
395
396 let vertex_layout = wgpu::VertexBufferLayout {
397 array_stride: core::mem::size_of::<TexVertex>() as wgpu::BufferAddress,
398 step_mode: wgpu::VertexStepMode::Vertex,
399 attributes: &attrs,
400 };
401
402 let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
403 label: Some("oxiui-render-wgpu textured pipeline"),
404 layout: Some(&pipeline_layout),
405 vertex: wgpu::VertexState {
406 module: &shader,
407 entry_point: Some("vs_main"),
408 buffers: &[vertex_layout],
409 compilation_options: wgpu::PipelineCompilationOptions::default(),
410 },
411 fragment: Some(wgpu::FragmentState {
412 module: &shader,
413 entry_point: Some("fs_main"),
414 targets: &[Some(wgpu::ColorTargetState {
415 format: TARGET_FORMAT,
416 blend: Some(wgpu::BlendState::ALPHA_BLENDING),
417 write_mask: wgpu::ColorWrites::ALL,
418 })],
419 compilation_options: wgpu::PipelineCompilationOptions::default(),
420 }),
421 primitive: wgpu::PrimitiveState {
422 topology: wgpu::PrimitiveTopology::TriangleList,
423 strip_index_format: None,
424 front_face: wgpu::FrontFace::Ccw,
425 cull_mode: None,
426 unclipped_depth: false,
427 polygon_mode: wgpu::PolygonMode::Fill,
428 conservative: false,
429 },
430 depth_stencil: None,
431 multisample: wgpu::MultisampleState {
432 count: sample_count,
433 mask: !0,
434 alpha_to_coverage_enabled: false,
435 },
436 multiview_mask: None,
437 cache: None,
438 });
439
440 Self {
441 pipeline,
442 globals_layout,
443 texture_layout,
444 }
445 }
446}
447
448pub struct BlurPipeline {
457 pub pipeline: wgpu::RenderPipeline,
459 pub globals_layout: wgpu::BindGroupLayout,
461 pub source_layout: wgpu::BindGroupLayout,
463}
464
465impl BlurPipeline {
466 pub fn new(device: &wgpu::Device, sample_count: u32) -> Self {
472 let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
473 label: Some("oxiui-render-wgpu blur.wgsl"),
474 source: wgpu::ShaderSource::Wgsl(include_str!("../shaders/blur.wgsl").into()),
475 });
476
477 let globals_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
479 label: Some("oxiui-render-wgpu blur globals layout"),
480 entries: &[wgpu::BindGroupLayoutEntry {
481 binding: 0,
482 visibility: wgpu::ShaderStages::VERTEX,
483 ty: wgpu::BindingType::Buffer {
484 ty: wgpu::BufferBindingType::Uniform,
485 has_dynamic_offset: false,
486 min_binding_size: None,
487 },
488 count: None,
489 }],
490 });
491
492 let source_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
494 label: Some("oxiui-render-wgpu blur source layout"),
495 entries: &[
496 wgpu::BindGroupLayoutEntry {
497 binding: 0,
498 visibility: wgpu::ShaderStages::FRAGMENT,
499 ty: wgpu::BindingType::Texture {
500 sample_type: wgpu::TextureSampleType::Float { filterable: true },
501 view_dimension: wgpu::TextureViewDimension::D2,
502 multisampled: false,
503 },
504 count: None,
505 },
506 wgpu::BindGroupLayoutEntry {
507 binding: 1,
508 visibility: wgpu::ShaderStages::FRAGMENT,
509 ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
510 count: None,
511 },
512 wgpu::BindGroupLayoutEntry {
513 binding: 2,
514 visibility: wgpu::ShaderStages::FRAGMENT,
515 ty: wgpu::BindingType::Buffer {
516 ty: wgpu::BufferBindingType::Uniform,
517 has_dynamic_offset: false,
518 min_binding_size: None,
519 },
520 count: None,
521 },
522 ],
523 });
524
525 let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
526 label: Some("oxiui-render-wgpu blur pipeline layout"),
527 bind_group_layouts: &[Some(&globals_layout), Some(&source_layout)],
528 immediate_size: 0,
529 });
530
531 let attrs = [
533 wgpu::VertexAttribute {
534 format: wgpu::VertexFormat::Float32x2,
535 offset: 0,
536 shader_location: 0,
537 },
538 wgpu::VertexAttribute {
539 format: wgpu::VertexFormat::Float32x2,
540 offset: 8,
541 shader_location: 1,
542 },
543 ];
544
545 let vertex_layout = wgpu::VertexBufferLayout {
546 array_stride: core::mem::size_of::<GradientVertex>() as wgpu::BufferAddress,
547 step_mode: wgpu::VertexStepMode::Vertex,
548 attributes: &attrs,
549 };
550
551 let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
552 label: Some("oxiui-render-wgpu blur pipeline"),
553 layout: Some(&pipeline_layout),
554 vertex: wgpu::VertexState {
555 module: &shader,
556 entry_point: Some("vs_main"),
557 buffers: &[vertex_layout],
558 compilation_options: wgpu::PipelineCompilationOptions::default(),
559 },
560 fragment: Some(wgpu::FragmentState {
561 module: &shader,
562 entry_point: Some("fs_main"),
563 targets: &[Some(wgpu::ColorTargetState {
564 format: TARGET_FORMAT,
565 blend: Some(wgpu::BlendState::ALPHA_BLENDING),
566 write_mask: wgpu::ColorWrites::ALL,
567 })],
568 compilation_options: wgpu::PipelineCompilationOptions::default(),
569 }),
570 primitive: wgpu::PrimitiveState {
571 topology: wgpu::PrimitiveTopology::TriangleList,
572 strip_index_format: None,
573 front_face: wgpu::FrontFace::Ccw,
574 cull_mode: None,
575 unclipped_depth: false,
576 polygon_mode: wgpu::PolygonMode::Fill,
577 conservative: false,
578 },
579 depth_stencil: None,
580 multisample: wgpu::MultisampleState {
581 count: sample_count,
582 mask: !0,
583 alpha_to_coverage_enabled: false,
584 },
585 multiview_mask: None,
586 cache: None,
587 });
588
589 Self {
590 pipeline,
591 globals_layout,
592 source_layout,
593 }
594 }
595}
596
597pub struct CompositePipeline {
604 pub pipeline: wgpu::RenderPipeline,
606 pub globals_layout: wgpu::BindGroupLayout,
608 pub source_layout: wgpu::BindGroupLayout,
610}
611
612impl CompositePipeline {
613 pub fn new(device: &wgpu::Device, sample_count: u32) -> Self {
619 let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
620 label: Some("oxiui-render-wgpu composite.wgsl"),
621 source: wgpu::ShaderSource::Wgsl(include_str!("../shaders/composite.wgsl").into()),
622 });
623
624 let globals_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
626 label: Some("oxiui-render-wgpu composite globals layout"),
627 entries: &[wgpu::BindGroupLayoutEntry {
628 binding: 0,
629 visibility: wgpu::ShaderStages::VERTEX,
630 ty: wgpu::BindingType::Buffer {
631 ty: wgpu::BufferBindingType::Uniform,
632 has_dynamic_offset: false,
633 min_binding_size: None,
634 },
635 count: None,
636 }],
637 });
638
639 let source_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
641 label: Some("oxiui-render-wgpu composite source layout"),
642 entries: &[
643 wgpu::BindGroupLayoutEntry {
644 binding: 0,
645 visibility: wgpu::ShaderStages::FRAGMENT,
646 ty: wgpu::BindingType::Texture {
647 sample_type: wgpu::TextureSampleType::Float { filterable: true },
648 view_dimension: wgpu::TextureViewDimension::D2,
649 multisampled: false,
650 },
651 count: None,
652 },
653 wgpu::BindGroupLayoutEntry {
654 binding: 1,
655 visibility: wgpu::ShaderStages::FRAGMENT,
656 ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
657 count: None,
658 },
659 wgpu::BindGroupLayoutEntry {
660 binding: 2,
661 visibility: wgpu::ShaderStages::FRAGMENT,
662 ty: wgpu::BindingType::Buffer {
663 ty: wgpu::BufferBindingType::Uniform,
664 has_dynamic_offset: false,
665 min_binding_size: None,
666 },
667 count: None,
668 },
669 ],
670 });
671
672 let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
673 label: Some("oxiui-render-wgpu composite pipeline layout"),
674 bind_group_layouts: &[Some(&globals_layout), Some(&source_layout)],
675 immediate_size: 0,
676 });
677
678 let attrs = [
680 wgpu::VertexAttribute {
681 format: wgpu::VertexFormat::Float32x2,
682 offset: 0,
683 shader_location: 0,
684 },
685 wgpu::VertexAttribute {
686 format: wgpu::VertexFormat::Float32x2,
687 offset: 8,
688 shader_location: 1,
689 },
690 ];
691
692 let vertex_layout = wgpu::VertexBufferLayout {
693 array_stride: core::mem::size_of::<GradientVertex>() as wgpu::BufferAddress,
694 step_mode: wgpu::VertexStepMode::Vertex,
695 attributes: &attrs,
696 };
697
698 let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
699 label: Some("oxiui-render-wgpu composite pipeline"),
700 layout: Some(&pipeline_layout),
701 vertex: wgpu::VertexState {
702 module: &shader,
703 entry_point: Some("vs_main"),
704 buffers: &[vertex_layout],
705 compilation_options: wgpu::PipelineCompilationOptions::default(),
706 },
707 fragment: Some(wgpu::FragmentState {
708 module: &shader,
709 entry_point: Some("fs_main"),
710 targets: &[Some(wgpu::ColorTargetState {
711 format: TARGET_FORMAT,
712 blend: Some(wgpu::BlendState::ALPHA_BLENDING),
713 write_mask: wgpu::ColorWrites::ALL,
714 })],
715 compilation_options: wgpu::PipelineCompilationOptions::default(),
716 }),
717 primitive: wgpu::PrimitiveState {
718 topology: wgpu::PrimitiveTopology::TriangleList,
719 strip_index_format: None,
720 front_face: wgpu::FrontFace::Ccw,
721 cull_mode: None,
722 unclipped_depth: false,
723 polygon_mode: wgpu::PolygonMode::Fill,
724 conservative: false,
725 },
726 depth_stencil: None,
727 multisample: wgpu::MultisampleState {
728 count: sample_count,
729 mask: !0,
730 alpha_to_coverage_enabled: false,
731 },
732 multiview_mask: None,
733 cache: None,
734 });
735
736 Self {
737 pipeline,
738 globals_layout,
739 source_layout,
740 }
741 }
742}