summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMicha White <botahamec@outlook.com>2022-09-18 21:18:23 -0400
committerMicha White <botahamec@outlook.com>2022-09-18 21:18:23 -0400
commit2d2c88a704455f5dc3e14b557bd52eefcec14d2e (patch)
treeb53f409d6e7fb7387816640bc76c88ebe7f8364c /src
parentcd7d74507fa54d026547b7dda9e1498a81a395b5 (diff)
Some optimization
Diffstat (limited to 'src')
-rw-r--r--src/config.rs6
-rw-r--r--src/renderer.rs128
-rw-r--r--src/vertex.rs4
3 files changed, 75 insertions, 63 deletions
diff --git a/src/config.rs b/src/config.rs
index e9f9ca4..c29a957 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -69,7 +69,7 @@ pub struct RenderWindowConfig<'a> {
/// The initial capacity of the instance buffer. The size will increase if
/// it's not large enough. Increasing this value may improve performance
/// towards the beginning, if a lot of instances are being created.
- pub instance_capacity: usize
+ pub instance_capacity: usize,
}
impl<'a> Default for RenderWindowConfig<'a> {
@@ -87,11 +87,13 @@ impl<'a> Default for RenderWindowConfig<'a> {
}
impl<'a> RenderWindowConfig<'a> {
- /// Create a `WindowBuilder` from the configuration given
+ /// Create a `WindowBuilder` from the configuration given. This window is
+ /// initially invisible and must later be made visible.
pub(crate) fn to_window(&self) -> WindowBuilder {
// start building the window
let mut builder = WindowBuilder::new()
.with_title(self.title.as_ref())
+ .with_visible(false)
.with_inner_size(LogicalSize::new(
self.default_width.get(),
self.default_height.get(),
diff --git a/src/renderer.rs b/src/renderer.rs
index 81e1a3f..492501f 100644
--- a/src/renderer.rs
+++ b/src/renderer.rs
@@ -50,6 +50,69 @@ pub struct Renderer {
// TODO make this more complete
impl Renderer {
+ fn get_adapter(
+ instance: &wgpu::Instance,
+ surface: &wgpu::Surface,
+ power_preference: wgpu::PowerPreference,
+ ) -> Result<wgpu::Adapter, NoGpuError> {
+ let adapter = instance
+ .request_adapter(&wgpu::RequestAdapterOptions {
+ power_preference,
+ compatible_surface: Some(surface),
+ force_fallback_adapter: false,
+ })
+ .block_on(); // TODO this takes too long
+
+ let adapter = adapter.or_else(|| {
+ instance
+ .enumerate_adapters(wgpu::Backends::all())
+ .find(|adapter| !surface.get_supported_formats(adapter).is_empty())
+ });
+
+ adapter.ok_or(NoGpuError::new())
+ }
+
+ fn sprite_render_pipeline(
+ device: &wgpu::Device,
+ texture_format: wgpu::TextureFormat,
+ ) -> wgpu::RenderPipeline {
+ let shader = device.create_shader_module(include_wgsl!("../shaders/sprite.wgsl"));
+ let render_pipeline_layout =
+ device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
+ label: Some("Sprite Render Pipeline Layout"),
+ ..Default::default()
+ });
+
+ device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
+ label: Some("Sprite Render Pipeline"),
+ layout: Some(&render_pipeline_layout),
+ // information about the vertex shader
+ vertex: wgpu::VertexState {
+ module: &shader,
+ entry_point: "vs_main",
+ buffers: &[Vertex::desc(), Instance::desc()],
+ },
+ // information about the fragment shader
+ fragment: Some(wgpu::FragmentState {
+ module: &shader,
+ entry_point: "fs_main",
+ targets: &[Some(wgpu::ColorTargetState {
+ format: texture_format,
+ blend: Some(wgpu::BlendState::REPLACE),
+ write_mask: wgpu::ColorWrites::ALL,
+ })],
+ }),
+ primitive: wgpu::PrimitiveState {
+ // don't render the back of a sprite
+ cull_mode: Some(wgpu::Face::Back),
+ ..Default::default()
+ },
+ depth_stencil: None,
+ multisample: wgpu::MultisampleState::default(),
+ multiview: None,
+ })
+ }
+
/// Initializes the renderer
///
/// # Errors
@@ -79,28 +142,15 @@ impl Renderer {
let power_preference = config.power_preference();
// the adapter is the handle to the GPU
- let adapter = instance
- .request_adapter(&wgpu::RequestAdapterOptions {
- power_preference,
- compatible_surface: Some(&surface),
- force_fallback_adapter: false,
- })
- .block_on();
- let adapter = adapter.or_else(|| {
- instance
- .enumerate_adapters(wgpu::Backends::all())
- .find(|adapter| !surface.get_supported_formats(adapter).is_empty())
- });
- let Some(adapter) = adapter else { return Err(NoGpuError::new().into()) };
+ let adapter = Self::get_adapter(&instance, &surface, power_preference)?;
// gets a connection to the device, as well as a handle to its command queue
// the options chosen here ensure that this is guaranteed to not panic
let (device, queue) = adapter
.request_device(
&wgpu::DeviceDescriptor {
- label: None,
features: wgpu::Features::empty(),
- limits: wgpu::Limits::default(),
+ ..Default::default()
},
None,
)
@@ -108,58 +158,15 @@ impl Renderer {
.expect("there was no device with the selected features");
// configuration for the surface
+ let surface_time = std::time::Instant::now();
let surface_config = config.to_surface_configuration(
&surface.get_supported_modes(&adapter),
surface.get_supported_formats(&adapter)[0],
);
-
surface.configure(&device, &surface_config);
// set up a pipeline for sprite rendering
- let shader = device.create_shader_module(include_wgsl!("../shaders/sprite.wgsl"));
- let render_pipeline_layout =
- device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
- label: Some("Render Pipeline Layout"),
- ..Default::default()
- });
- let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
- label: Some("Render Pipeline"),
- layout: Some(&render_pipeline_layout),
- // information about the vertex shader
- vertex: wgpu::VertexState {
- module: &shader,
- entry_point: "vs_main",
- buffers: &[Vertex::desc(), Instance::desc()],
- },
- // information about the fragment shader
- fragment: Some(wgpu::FragmentState {
- module: &shader,
- entry_point: "fs_main",
- targets: &[Some(wgpu::ColorTargetState {
- format: surface_config.format,
- blend: Some(wgpu::BlendState::REPLACE),
- write_mask: wgpu::ColorWrites::ALL,
- })],
- }),
- primitive: wgpu::PrimitiveState {
- // save some memory
- topology: wgpu::PrimitiveTopology::TriangleStrip,
- strip_index_format: None,
- front_face: wgpu::FrontFace::Ccw,
- // don't render the back of a sprite
- cull_mode: Some(wgpu::Face::Back),
- polygon_mode: wgpu::PolygonMode::Fill,
- unclipped_depth: false,
- conservative: false,
- },
- depth_stencil: None,
- multisample: wgpu::MultisampleState {
- count: 1,
- mask: !0,
- alpha_to_coverage_enabled: false,
- },
- multiview: None,
- });
+ let render_pipeline = Self::sprite_render_pipeline(&device, surface_config.format);
// the vertex buffer used for rendering squares
let square_vertices = SQUARE
@@ -282,6 +289,7 @@ impl Renderer {
/// Run the renderer indefinitely
pub fn run(mut self, event_loop: EventLoop<()>) -> ! {
+ self.window.set_visible(true);
event_loop.run(move |event, _, control_flow| match event {
Event::WindowEvent { window_id, event } => {
if window_id == self.window.id() {
diff --git a/src/vertex.rs b/src/vertex.rs
index 6514fd3..a24a601 100644
--- a/src/vertex.rs
+++ b/src/vertex.rs
@@ -3,11 +3,13 @@ use std::mem::size_of;
use bytemuck::{Pod, Zeroable};
/// The vertices needed to form a square
-pub const SQUARE: [Vertex; 4] = [
+pub const SQUARE: [Vertex; 6] = [
Vertex::new(-0.5, -0.5),
Vertex::new(0.5, -0.5),
Vertex::new(-0.5, 0.5),
Vertex::new(0.5, 0.5),
+ Vertex::new(-0.5, 0.5),
+ Vertex::new(0.5, -0.5),
];
#[repr(C)]