mirror of https://github.com/sotrh/learn-wgpu
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
4.9 KiB
Rust
143 lines
4.9 KiB
Rust
5 years ago
|
fn main() {
|
||
5 years ago
|
let adapter = wgpu::Adapter::request(&wgpu::RequestAdapterOptions {
|
||
|
..Default::default()
|
||
|
}).unwrap();
|
||
|
let (device, mut queue) = adapter.request_device(&Default::default());
|
||
5 years ago
|
|
||
5 years ago
|
let texture_size = 256u32;
|
||
5 years ago
|
let texture_desc = wgpu::TextureDescriptor {
|
||
|
size: wgpu::Extent3d {
|
||
|
width: texture_size,
|
||
|
height: texture_size,
|
||
|
depth: 1,
|
||
|
},
|
||
|
array_layer_count: 1,
|
||
5 years ago
|
mip_level_count: 1,
|
||
5 years ago
|
sample_count: 1,
|
||
|
dimension: wgpu::TextureDimension::D2,
|
||
|
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
||
4 years ago
|
usage: wgpu::TextureUsage::COPY_SRC
|
||
4 years ago
|
| wgpu::TextureUsage::OUTPUT_ATTACHMENT
|
||
|
,
|
||
5 years ago
|
};
|
||
|
let texture = device.create_texture(&texture_desc);
|
||
|
let texture_view = texture.create_default_view();
|
||
|
|
||
5 years ago
|
let u32_size = std::mem::size_of::<u32>() as u32;
|
||
|
let output_buffer_size = (u32_size * texture_size * texture_size) as wgpu::BufferAddress;
|
||
5 years ago
|
let output_buffer_desc = wgpu::BufferDescriptor {
|
||
|
size: output_buffer_size,
|
||
4 years ago
|
usage: wgpu::BufferUsage::COPY_DST
|
||
5 years ago
|
| wgpu::BufferUsage::MAP_READ
|
||
|
,
|
||
5 years ago
|
};
|
||
|
let output_buffer = device.create_buffer(&output_buffer_desc);
|
||
|
|
||
5 years ago
|
let vs_src = include_str!("shader.vert");
|
||
|
let fs_src = include_str!("shader.frag");
|
||
|
let vs_spirv = glsl_to_spirv::compile(vs_src, glsl_to_spirv::ShaderType::Vertex).unwrap();
|
||
|
let fs_spirv = glsl_to_spirv::compile(fs_src, glsl_to_spirv::ShaderType::Fragment).unwrap();
|
||
|
let vs_data = wgpu::read_spirv(vs_spirv).unwrap();
|
||
|
let fs_data = wgpu::read_spirv(fs_spirv).unwrap();
|
||
|
let vs_module = device.create_shader_module(&vs_data);
|
||
|
let fs_module = device.create_shader_module(&fs_data);
|
||
|
|
||
|
let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||
|
bind_group_layouts: &[],
|
||
|
});
|
||
|
|
||
|
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||
|
layout: &render_pipeline_layout,
|
||
|
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||
|
module: &vs_module,
|
||
|
entry_point: "main",
|
||
|
},
|
||
|
fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
|
||
|
module: &fs_module,
|
||
|
entry_point: "main",
|
||
|
}),
|
||
|
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||
|
front_face: wgpu::FrontFace::Ccw,
|
||
|
cull_mode: wgpu::CullMode::Back,
|
||
|
depth_bias: 0,
|
||
|
depth_bias_slope_scale: 0.0,
|
||
|
depth_bias_clamp: 0.0,
|
||
|
}),
|
||
|
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
|
||
|
color_states: &[
|
||
|
wgpu::ColorStateDescriptor {
|
||
|
format: texture_desc.format,
|
||
|
color_blend: wgpu::BlendDescriptor::REPLACE,
|
||
|
alpha_blend: wgpu::BlendDescriptor::REPLACE,
|
||
|
write_mask: wgpu::ColorWrite::ALL,
|
||
|
},
|
||
|
],
|
||
|
depth_stencil_state: None,
|
||
|
index_format: wgpu::IndexFormat::Uint16,
|
||
|
vertex_buffers: &[],
|
||
|
sample_count: 1,
|
||
|
sample_mask: !0,
|
||
|
alpha_to_coverage_enabled: false,
|
||
|
});
|
||
|
|
||
5 years ago
|
let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||
|
todo: 0,
|
||
|
});
|
||
|
|
||
|
{
|
||
|
let render_pass_desc = wgpu::RenderPassDescriptor {
|
||
|
color_attachments: &[
|
||
|
wgpu::RenderPassColorAttachmentDescriptor {
|
||
|
attachment: &texture_view,
|
||
|
resolve_target: None,
|
||
|
load_op: wgpu::LoadOp::Clear,
|
||
|
store_op: wgpu::StoreOp::Store,
|
||
5 years ago
|
clear_color: wgpu::Color {
|
||
|
r: 0.1,
|
||
|
g: 0.2,
|
||
|
b: 0.3,
|
||
|
a: 1.0,
|
||
|
},
|
||
5 years ago
|
}
|
||
|
],
|
||
|
depth_stencil_attachment: None,
|
||
|
};
|
||
|
let mut render_pass = encoder.begin_render_pass(&render_pass_desc);
|
||
5 years ago
|
|
||
|
render_pass.set_pipeline(&render_pipeline);
|
||
|
render_pass.draw(0..3, 0..1);
|
||
5 years ago
|
}
|
||
|
|
||
|
encoder.copy_texture_to_buffer(
|
||
|
wgpu::TextureCopyView {
|
||
|
texture: &texture,
|
||
|
mip_level: 0,
|
||
5 years ago
|
array_layer: 0,
|
||
5 years ago
|
origin: wgpu::Origin3d::ZERO,
|
||
4 years ago
|
},
|
||
5 years ago
|
wgpu::BufferCopyView {
|
||
|
buffer: &output_buffer,
|
||
|
offset: 0,
|
||
5 years ago
|
row_pitch: u32_size * texture_size,
|
||
5 years ago
|
image_height: texture_size,
|
||
4 years ago
|
},
|
||
5 years ago
|
texture_desc.size,
|
||
|
);
|
||
|
|
||
5 years ago
|
queue.submit(&[encoder.finish()]);
|
||
5 years ago
|
|
||
|
output_buffer.map_read_async(0, output_buffer_size, move |result: wgpu::BufferMapAsyncResult<&[u8]>| {
|
||
|
let mapping = result.unwrap();
|
||
|
let data = mapping.data;
|
||
|
|
||
|
use image::{ImageBuffer, Rgba};
|
||
|
let buffer = ImageBuffer::<Rgba<u8>, _>::from_raw(
|
||
|
texture_size,
|
||
|
texture_size,
|
||
|
data,
|
||
|
).unwrap();
|
||
|
|
||
|
buffer.save("image.png").unwrap();
|
||
|
});
|
||
4 years ago
|
}
|