Skip to content

Commit 14f6d2c

Browse files
committed
refactor render pipeline creation
1 parent abe6861 commit 14f6d2c

File tree

4 files changed

+65
-85
lines changed

4 files changed

+65
-85
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "fractal_viewer"
3-
version = "2.1.1"
3+
version = "2.1.2"
44
edition = "2021"
55
description = "Cross-platform GPU-accelerated viewer for the Mandelbrot set and related fractals"
66
repository = "https://github.com/arthomnix/fractal_viewer"

src/lib.rs

Lines changed: 59 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ mod uniforms;
33
#[cfg(target_arch = "wasm32")]
44
mod web;
55

6-
use egui_wgpu::wgpu as wgpu;
6+
use egui_wgpu::wgpu;
77
#[cfg(not(target_arch = "wasm32"))]
8-
use egui_wgpu::wgpu::naga as naga;
8+
use egui_wgpu::wgpu::naga;
99

1010
use crate::settings::{CustomShaderData, UserSettings};
1111
use crate::uniforms::{calculate_scale, Uniforms};
@@ -120,50 +120,23 @@ impl FractalViewerApp {
120120
}],
121121
});
122122

123-
let shader = device.create_shader_module(ShaderModuleDescriptor {
124-
label: Some("fv_shader"),
125-
source: ShaderSource::Wgsl(settings.shader_data.shader().into()),
126-
});
127-
128-
let pipeline_layout = device.create_pipeline_layout(&PipelineLayoutDescriptor {
129-
label: Some("fv_pipeline_layout"),
130-
bind_group_layouts: &[&uniform_bind_group_layout],
131-
push_constant_ranges: &[],
132-
});
123+
let renderer_state = RendererState {
124+
device: Arc::clone(device),
125+
target_format: wgpu_render_state.target_format.into(),
126+
bind_group_layout: uniform_bind_group_layout,
127+
bind_group: uniform_bind_group,
128+
uniform_buffer,
129+
};
133130

134-
let pipeline = device.create_render_pipeline(&RenderPipelineDescriptor {
135-
label: Some("fv_pipeline"),
136-
layout: Some(&pipeline_layout),
137-
vertex: VertexState {
138-
module: &shader,
139-
entry_point: "vs_main",
140-
compilation_options: Default::default(),
141-
buffers: &[],
142-
},
143-
fragment: Some(FragmentState {
144-
module: &shader,
145-
entry_point: "fs_main",
146-
compilation_options: Default::default(),
147-
targets: &[Some(wgpu_render_state.target_format.into())],
148-
}),
149-
primitive: PrimitiveState::default(),
150-
depth_stencil: None,
151-
multisample: MultisampleState::default(),
152-
multiview: None,
153-
cache: None,
154-
});
131+
let pipeline = renderer_state.generate_pipeline(&settings.shader_data);
155132

156133
wgpu_render_state
157134
.renderer
158135
.write()
159136
.callback_resources
160137
.insert(FvRenderer {
161-
device: Arc::clone(device),
162138
pipeline,
163-
target_format: wgpu_render_state.target_format.into(),
164-
bind_group: uniform_bind_group,
165-
bind_group_layout: uniform_bind_group_layout,
166-
uniform_buffer,
139+
state: renderer_state,
167140
});
168141

169142
let adapter_info = wgpu_render_state.adapter.get_info();
@@ -488,68 +461,75 @@ impl eframe::App for FractalViewerApp {
488461
}
489462
}
490463

491-
struct FvRenderer {
464+
struct RendererState {
492465
device: Arc<Device>,
493-
pipeline: RenderPipeline,
494466
target_format: ColorTargetState,
495467
bind_group_layout: BindGroupLayout,
496468
bind_group: BindGroup,
497469
uniform_buffer: Buffer,
498470
}
499471

500-
impl FvRenderer {
501-
fn prepare(&mut self, queue: &Queue, callback: &FvRenderCallback) {
502-
if let Some(data) = &callback.shader_recompilation_options {
503-
let shader = self.device.create_shader_module(ShaderModuleDescriptor {
504-
label: Some("fv_shader"),
505-
source: ShaderSource::Wgsl(data.shader().into()),
472+
impl RendererState {
473+
fn generate_pipeline(&self, shader_data: &CustomShaderData) -> RenderPipeline {
474+
let shader = self.device.create_shader_module(ShaderModuleDescriptor {
475+
label: Some("fv_shader"),
476+
source: ShaderSource::Wgsl(shader_data.shader().into()),
477+
});
478+
479+
let pipeline_layout = self
480+
.device
481+
.create_pipeline_layout(&PipelineLayoutDescriptor {
482+
label: Some("fv_pipeline_layout"),
483+
bind_group_layouts: &[&self.bind_group_layout],
484+
push_constant_ranges: &[],
506485
});
507486

508-
let pipeline_layout = self
509-
.device
510-
.create_pipeline_layout(&PipelineLayoutDescriptor {
511-
label: Some("fv_pipeline_layout"),
512-
bind_group_layouts: &[&self.bind_group_layout],
513-
push_constant_ranges: &[],
514-
});
487+
self.device
488+
.create_render_pipeline(&RenderPipelineDescriptor {
489+
label: Some("fv_pipeline"),
490+
layout: Some(&pipeline_layout),
491+
vertex: VertexState {
492+
module: &shader,
493+
entry_point: "vs_main",
494+
compilation_options: Default::default(),
495+
buffers: &[],
496+
},
497+
fragment: Some(FragmentState {
498+
module: &shader,
499+
entry_point: "fs_main",
500+
compilation_options: Default::default(),
501+
targets: &[Some(self.target_format.clone())],
502+
}),
503+
primitive: PrimitiveState::default(),
504+
depth_stencil: None,
505+
multisample: MultisampleState::default(),
506+
multiview: None,
507+
cache: None,
508+
})
509+
}
510+
}
515511

516-
let pipeline = self
517-
.device
518-
.create_render_pipeline(&RenderPipelineDescriptor {
519-
label: Some("fv_pipeline"),
520-
layout: Some(&pipeline_layout),
521-
vertex: VertexState {
522-
module: &shader,
523-
entry_point: "vs_main",
524-
compilation_options: Default::default(),
525-
buffers: &[],
526-
},
527-
fragment: Some(FragmentState {
528-
module: &shader,
529-
entry_point: "fs_main",
530-
compilation_options: Default::default(),
531-
targets: &[Some(self.target_format.clone())],
532-
}),
533-
primitive: PrimitiveState::default(),
534-
depth_stencil: None,
535-
multisample: MultisampleState::default(),
536-
multiview: None,
537-
cache: None,
538-
});
512+
struct FvRenderer {
513+
pipeline: RenderPipeline,
514+
state: RendererState,
515+
}
539516

540-
self.pipeline = pipeline;
517+
impl FvRenderer {
518+
fn prepare(&mut self, queue: &Queue, callback: &FvRenderCallback) {
519+
if let Some(data) = &callback.shader_recompilation_options {
520+
self.pipeline = self.state.generate_pipeline(data);
541521
}
542522

543523
queue.write_buffer(
544-
&self.uniform_buffer,
524+
&self.state.uniform_buffer,
545525
0,
546526
bytemuck::cast_slice(&[callback.uniforms]),
547527
);
548528
}
549529

550530
fn paint(&self, render_pass: &mut RenderPass<'static>) {
551531
render_pass.set_pipeline(&self.pipeline);
552-
render_pass.set_bind_group(0, &self.bind_group, &[]);
532+
render_pass.set_bind_group(0, &self.state.bind_group, &[]);
553533
render_pass.draw(0..6, 0..1);
554534
}
555535
}

src/settings/compat.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,12 +161,11 @@ pub(crate) mod v0_5 {
161161
}
162162
}
163163

164-
165164
pub(crate) mod v2_0 {
166165
use crate::settings::{CustomShaderData, InvalidSettingsImportError};
167166

168-
use base64::Engine;
169167
use base64::engine::general_purpose;
168+
use base64::Engine;
170169

171170
#[derive(Clone, serde::Serialize, serde::Deserialize)]
172171
pub(crate) struct UserSettings {
@@ -215,4 +214,4 @@ pub(crate) mod v2_0 {
215214
}
216215
}
217216
}
218-
}
217+
}

src/settings/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
mod compat;
22

3+
use crate::SHADER;
34
use base64::{engine::general_purpose, Engine};
45
use std::fmt::{Display, Formatter};
5-
use crate::SHADER;
66

77
#[derive(Debug, serde::Deserialize)]
88
pub enum InvalidSettingsImportError {
@@ -127,7 +127,8 @@ impl Default for CustomShaderData {
127127
fn default() -> Self {
128128
Self {
129129
equation: "csquare(z) + c".to_string(),
130-
colour: "hsv_rgb(vec3(log(n + 1.0) / log(f32(uniforms.iterations) + 1.0), 0.8, 0.8))".to_string(),
130+
colour: "hsv_rgb(vec3(log(n + 1.0) / log(f32(uniforms.iterations) + 1.0), 0.8, 0.8))"
131+
.to_string(),
131132
additional: String::new(),
132133
}
133134
}

0 commit comments

Comments
 (0)