summaryrefslogtreecommitdiffstats
path: root/src/wgpuctx/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/wgpuctx/mod.rs')
-rw-r--r--src/wgpuctx/mod.rs245
1 files changed, 245 insertions, 0 deletions
diff --git a/src/wgpuctx/mod.rs b/src/wgpuctx/mod.rs
new file mode 100644
index 0000000..f8aa3ec
--- /dev/null
+++ b/src/wgpuctx/mod.rs
@@ -0,0 +1,245 @@
+use std::sync::Arc;
+use std::error::Error;
+use wgpu::util::DeviceExt;
+use winit::window::{Window};
+
+use crate::texture::Texture;
+
+pub mod pipeline;
+
+pub struct WgpuCtx
+{
+ surface: wgpu::Surface<'static>,
+ surface_conf: wgpu::SurfaceConfiguration,
+ surface_texture: Option<wgpu::SurfaceTexture>,
+ is_configured: bool,
+
+ adapter: wgpu::Adapter,
+ device: wgpu::Device,
+ queue: wgpu::Queue,
+}
+
+pub struct RenderPassBuilder<'encoder>
+{
+ label: &'static str,
+ view: &'encoder wgpu::TextureView,
+ clear_color: wgpu::Color
+}
+
+impl WgpuCtx
+{
+ pub async fn new(
+ instance: &wgpu::Instance,
+ window: Arc<Window>,
+ ) -> Self {
+ let surface = instance.create_surface(window.clone()).unwrap();
+
+ let adapter = instance
+ .request_adapter(&wgpu::RequestAdapterOptions {
+ compatible_surface: Some(&surface),
+ ..Default::default()
+ }).await.expect("Failed to find valid adapter");
+
+ let (device, queue) = adapter
+ .request_device(&wgpu::DeviceDescriptor {
+ label: None,
+ required_features: wgpu::Features::empty(),
+ required_limits: wgpu::Limits::downlevel_defaults(),
+ experimental_features: wgpu::ExperimentalFeatures::disabled(),
+ memory_hints: wgpu::MemoryHints::Performance,
+ trace: wgpu::Trace::Off
+ }).await.expect("Failed to find device and queue");
+
+ let size = window.inner_size();
+ let surface_config = surface.get_default_config(&adapter, size.width, size.height).unwrap();
+
+ Self {
+ surface: surface,
+ surface_conf: surface_config,
+ surface_texture: None,
+ is_configured: false,
+ adapter: adapter,
+ device: device,
+ queue: queue
+ }
+ }
+
+ pub fn resize(
+ &mut self,
+ width: u32,
+ height: u32)
+ {
+ self.surface_conf.width = width;
+ self.surface_conf.height = height;
+ self.surface.configure(&self.device, &self.surface_conf);
+ self.is_configured = true;
+ }
+
+ pub fn is_ready(
+ &self)
+ -> bool {
+ self.is_configured
+ }
+
+ pub fn surface_config(
+ &self)
+ -> wgpu::SurfaceConfiguration {
+ self.surface_conf.clone()
+ }
+
+ pub fn adapter(
+ &self)
+ -> &wgpu::Adapter {
+ &self.adapter
+ }
+
+ pub fn device(
+ &self)
+ -> &wgpu::Device {
+ &self.device
+ }
+
+ pub fn queue(
+ &self)
+ -> &wgpu::Queue {
+ &self.queue
+ }
+
+ pub fn prepare_surface(
+ &mut self,
+ view_descr: &wgpu::TextureViewDescriptor)
+ -> Result<wgpu::TextureView, wgpu::SurfaceError>
+ {
+ let texture = self.surface.get_current_texture()?;
+ let view = texture.texture.create_view(view_descr);
+
+ self.surface_texture = Some(texture);
+ Ok(view)
+ }
+
+ pub fn create_encoder(
+ &self,
+ descr: &wgpu::CommandEncoderDescriptor)
+ -> wgpu::CommandEncoder
+ {
+ self.device.create_command_encoder(descr)
+ }
+
+ pub fn create_default_encoder(
+ &self,
+ label: &'static str)
+ -> wgpu::CommandEncoder {
+ self.create_encoder(
+ &wgpu::CommandEncoderDescriptor {
+ label: Some(label)
+ }
+ )
+ }
+
+ pub fn submit_encoder(
+ &self,
+ encoder: wgpu::CommandEncoder)
+ {
+ self.queue.submit(std::iter::once(encoder.finish()));
+ }
+
+ pub fn present_surface(
+ &mut self)
+ {
+ let texture = self.surface_texture.take();
+ match texture {
+ Some(t) => t.present(),
+ None => {}
+ }
+ }
+
+ pub fn create_shader(
+ &self,
+ module_descr: wgpu::ShaderModuleDescriptor)
+ -> wgpu::ShaderModule {
+ self.device.create_shader_module(module_descr)
+ }
+
+ pub fn create_pipeline_layout(
+ &self,
+ layout_descr: &wgpu::PipelineLayoutDescriptor)
+ -> wgpu::PipelineLayout {
+ self.device.create_pipeline_layout(layout_descr)
+ }
+
+ pub fn create_render_pipeline(
+ &self,
+ pipeline_layout: &wgpu::RenderPipelineDescriptor)
+ -> wgpu::RenderPipeline {
+ self.device.create_render_pipeline(pipeline_layout)
+ }
+
+ pub fn create_buffer_init(
+ &self,
+ descr: &wgpu::util::BufferInitDescriptor
+ ) -> wgpu::Buffer {
+ self.device.create_buffer_init(descr)
+ }
+
+ pub fn create_buffer(
+ &self,
+ descr: &wgpu::BufferDescriptor)
+ -> wgpu::Buffer {
+ self.device.create_buffer(descr)
+ }
+
+ pub fn new_texture(
+ &self,
+ descr: wgpu::TextureDescriptor)
+ -> Texture
+ {
+ Texture::new(&self.device, descr)
+ }
+
+} //impl WgpuCtx
+
+impl<'encoder> RenderPassBuilder<'encoder>
+{
+ pub fn new(
+ label: &'static str,
+ view: &'encoder wgpu::TextureView)
+ -> Self {
+ Self {
+ label: label,
+ view: view,
+ clear_color: wgpu::Color { r: 0.0, g: 0.0, b: 0.0, a: 1.0 }
+ }
+ }
+
+ pub fn clear_color(
+ mut self,
+ color: wgpu::Color)
+ -> Self {
+ self.clear_color = color;
+ self
+ }
+
+ pub fn build(
+ self,
+ encoder: &'encoder mut wgpu::CommandEncoder)
+ -> wgpu::RenderPass<'encoder>
+ {
+ encoder.begin_render_pass(
+ &wgpu::RenderPassDescriptor {
+ label: Some(self.label),
+ color_attachments: &[Some(wgpu::RenderPassColorAttachment {
+ view: self.view,
+ resolve_target: None,
+ depth_slice: None,
+ ops: wgpu::Operations {
+ load: wgpu::LoadOp::Clear(self.clear_color),
+ store: wgpu::StoreOp::Store
+ }
+ })],
+ depth_stencil_attachment: None,
+ occlusion_query_set: None,
+ timestamp_writes: None,
+ }
+ )
+ }
+}