Last active
April 11, 2024 13:18
-
-
Save RedMindZ/eb1033b0b903d35f5cfba6919bcad25d to your computer and use it in GitHub Desktop.
Minimal example to reproduce https://github.com/gfx-rs/wgpu/issues/5514
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "wgpu_command_encoder" | |
version = "0.1.0" | |
edition = "2021" | |
[dependencies] | |
pollster = "0.3.0" | |
wgpu = "0.19.1" | |
winit = "0.29" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::borrow::Cow; | |
use wgpu::{BufferDescriptor, BufferUsages}; | |
use winit::{ | |
event::{Event, WindowEvent}, | |
event_loop::EventLoop, | |
window::Window, | |
}; | |
async fn run(event_loop: EventLoop<()>, window: Window) { | |
let mut size = window.inner_size(); | |
size.width = size.width.max(1); | |
size.height = size.height.max(1); | |
let instance = wgpu::Instance::default(); | |
let surface = instance.create_surface(&window).unwrap(); | |
let adapter = instance | |
.request_adapter(&wgpu::RequestAdapterOptions { | |
power_preference: wgpu::PowerPreference::default(), | |
force_fallback_adapter: false, | |
// Request an adapter which can render to our surface | |
compatible_surface: Some(&surface), | |
}) | |
.await | |
.expect("Failed to find an appropriate adapter"); | |
// Create the logical device and command queue | |
let (device, queue) = adapter | |
.request_device( | |
&wgpu::DeviceDescriptor { | |
label: None, | |
required_features: wgpu::Features::empty(), | |
// Make sure we use the texture resolution limits from the adapter, so we can support images the size of the swapchain. | |
required_limits: wgpu::Limits::downlevel_webgl2_defaults() | |
.using_resolution(adapter.limits()), | |
}, | |
None, | |
) | |
.await | |
.expect("Failed to create device"); | |
// Load the shaders from disk | |
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { | |
label: None, | |
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))), | |
}); | |
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { | |
label: None, | |
bind_group_layouts: &[], | |
push_constant_ranges: &[], | |
}); | |
let swapchain_capabilities = surface.get_capabilities(&adapter); | |
let swapchain_format = swapchain_capabilities.formats[0]; | |
let mut buffers = Vec::new(); | |
for _ in 0..2_000_000 { | |
buffers.push(device.create_buffer(&BufferDescriptor { | |
label: Some("Vertex Buffer"), | |
size: 256, | |
usage: BufferUsages::VERTEX, | |
mapped_at_creation: false, | |
})); | |
} | |
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { | |
label: None, | |
layout: Some(&pipeline_layout), | |
vertex: wgpu::VertexState { | |
module: &shader, | |
entry_point: "vs_main", | |
buffers: &[], | |
}, | |
fragment: Some(wgpu::FragmentState { | |
module: &shader, | |
entry_point: "fs_main", | |
targets: &[Some(swapchain_format.into())], | |
}), | |
primitive: wgpu::PrimitiveState::default(), | |
depth_stencil: None, | |
multisample: wgpu::MultisampleState::default(), | |
multiview: None, | |
}); | |
let mut config = surface | |
.get_default_config(&adapter, size.width, size.height) | |
.unwrap(); | |
surface.configure(&device, &config); | |
let window = &window; | |
event_loop | |
.run(move |event, target| { | |
// Have the closure take ownership of the resources. | |
// `event_loop.run` never returns, therefore we must do this to ensure | |
// the resources are properly cleaned up. | |
let _ = (&instance, &adapter, &shader, &pipeline_layout); | |
if let Event::WindowEvent { | |
window_id: _, | |
event, | |
} = event | |
{ | |
match event { | |
WindowEvent::Resized(new_size) => { | |
// Reconfigure the surface with the new size | |
config.width = new_size.width.max(1); | |
config.height = new_size.height.max(1); | |
surface.configure(&device, &config); | |
// On macos the window needs to be redrawn manually after resizing | |
window.request_redraw(); | |
} | |
WindowEvent::RedrawRequested => { | |
let frame = surface | |
.get_current_texture() | |
.expect("Failed to acquire next swap chain texture"); | |
let view = frame | |
.texture | |
.create_view(&wgpu::TextureViewDescriptor::default()); | |
let mut encoder = | |
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { | |
label: None, | |
}); | |
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { | |
label: None, | |
color_attachments: &[Some(wgpu::RenderPassColorAttachment { | |
view: &view, | |
resolve_target: None, | |
ops: wgpu::Operations { | |
load: wgpu::LoadOp::Clear(wgpu::Color::GREEN), | |
store: wgpu::StoreOp::Store, | |
}, | |
})], | |
depth_stencil_attachment: None, | |
timestamp_writes: None, | |
occlusion_query_set: None, | |
}); | |
rpass.set_pipeline(&render_pipeline); | |
rpass.draw(0..3, 0..1); | |
let start_time = std::time::Instant::now(); | |
drop(rpass); | |
let encoding_time = start_time.elapsed(); | |
println!("Render pass encoded in: {:?}", encoding_time); | |
queue.submit(Some(encoder.finish())); | |
frame.present(); | |
} | |
WindowEvent::CloseRequested => target.exit(), | |
_ => {} | |
}; | |
} | |
}) | |
.unwrap(); | |
} | |
pub fn main() { | |
let event_loop = EventLoop::new().unwrap(); | |
#[allow(unused_mut)] | |
let mut builder = winit::window::WindowBuilder::new(); | |
let window = builder.build(&event_loop).unwrap(); | |
pollster::block_on(run(event_loop, window)); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@vertex | |
fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4<f32> { | |
let x = f32(i32(in_vertex_index) - 1); | |
let y = f32(i32(in_vertex_index & 1u) * 2 - 1); | |
return vec4<f32>(x, y, 0.0, 1.0); | |
} | |
@fragment | |
fn fs_main() -> @location(0) vec4<f32> { | |
return vec4<f32>(1.0, 0.0, 0.0, 1.0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment