From 0bd709fc8bbaed104ab13eed6910ca9a15a6b2b6 Mon Sep 17 00:00:00 2001 From: numzero Date: Sat, 11 Jan 2025 01:18:20 +0300 Subject: [PATCH] Basic shader test --- src/main.rs | 45 +++++++++++++++++++++++++++++++++++++++++---- src/present.wgsl | 28 ++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 src/present.wgsl diff --git a/src/main.rs b/src/main.rs index 699205b..64f15dc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ use std::error::Error; +use glam::uvec2; use winit::{ event::{Event, WindowEvent}, event_loop::EventLoop, @@ -15,22 +16,56 @@ fn main() { .unwrap(); let (device, queue, surface) = pollster::block_on(init_gpu(window)).unwrap(); - let format = wgpu::TextureFormat::Bgra8UnormSrgb; let mut surface_configured = false; + + let present_shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { + label: Some("present"), + source: wgpu::ShaderSource::Wgsl(include_str!("present.wgsl").into()), + }); + let present_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: None, + layout: None, + vertex: wgpu::VertexState { + module: &present_shader, + entry_point: None, + compilation_options: wgpu::PipelineCompilationOptions::default(), + buffers: &[], + }, + primitive: wgpu::PrimitiveState { + topology: wgpu::PrimitiveTopology::TriangleStrip, + ..Default::default() + }, + depth_stencil: None, + multisample: wgpu::MultisampleState::default(), + fragment: Some(wgpu::FragmentState { + module: &present_shader, + entry_point: None, + compilation_options: wgpu::PipelineCompilationOptions::default(), + targets: &[Some(wgpu::ColorTargetState { + format, + blend: None, + write_mask: wgpu::ColorWrites::ALL, + })], + }), + multiview: None, + cache: None, + }); + #[allow(deprecated)] event_loop .run(move |event, control_flow| match event { Event::WindowEvent { ref event, window_id } if window_id == window.id() => match event { WindowEvent::CloseRequested => control_flow.exit(), WindowEvent::Resized(physical_size) => { + let size = uvec2(physical_size.width, physical_size.height); surface.configure( &device, &wgpu::SurfaceConfiguration { usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::COPY_DST, format, - width: physical_size.width, - height: physical_size.height, + width: size.x, + height: size.y, present_mode: wgpu::PresentMode::Fifo, alpha_mode: wgpu::CompositeAlphaMode::Auto, view_formats: vec![], @@ -46,7 +81,7 @@ fn main() { let output = surface.get_current_texture().unwrap(); let view = output.texture.create_view(&wgpu::TextureViewDescriptor::default()); let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); - let render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { label: None, color_attachments: &[Some(wgpu::RenderPassColorAttachment { view: &view, @@ -60,6 +95,8 @@ fn main() { occlusion_query_set: None, timestamp_writes: None, }); + render_pass.set_pipeline(&present_pipeline); + render_pass.draw(0..4, 0..1); drop(render_pass); queue.submit(std::iter::once(encoder.finish())); output.present(); diff --git a/src/present.wgsl b/src/present.wgsl new file mode 100644 index 0000000..0663c5c --- /dev/null +++ b/src/present.wgsl @@ -0,0 +1,28 @@ +const SEED = 0x4ae95672u; + +struct Varying { + @location(0) uv: vec2f, + @builtin(position) screen: vec4f, +} + +@vertex +fn on_vertex(@builtin(vertex_index) vi: u32) -> Varying { + let uv = vec2f(vec2(vi, vi >> 1u) & vec2(1u)); + let screen = vec4(uv * 2. - 1., 0., 1.); + return Varying(vec2(uv.x, 1. - uv.y), screen); +} + +@fragment +fn on_fragment(in: Varying) -> @location(0) vec4f { + let x = bitcast(in.uv.x); + let y = bitcast(in.uv.y); + let rand = hash(hash(hash(SEED) ^ hash(x)) ^ hash(y)); + return vec4f(f32(rand) / 0x1p32); +} + +fn hash(key : u32) -> u32 { + var v = key; + v *= 0xb384af1bu; + v ^= v >> 15u; + return v; +}