render: Update wgpu to 0.6

This commit is contained in:
Nathan Adams 2020-08-27 12:32:41 +02:00 committed by Mike Welsh
parent 2e8521e9c0
commit 34fc3c574b
9 changed files with 897 additions and 409 deletions

501
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@ image = "0.23.8"
log = "0.4"
sample = "0.11.0"
futures = "0.3.4"
wgpu = "0.5"
wgpu = "0.6"
wgpu-native = "0.5"
path-slash = "0.1.3"
walkdir = "2.3.1"

View File

@ -332,23 +332,23 @@ fn capture_multiple_swfs(
fn main() -> Result<(), Box<dyn Error>> {
let opt: Opt = Opt::parse();
let adapter = block_on(wgpu::Adapter::request(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
compatible_surface: None,
},
wgpu::BackendBit::PRIMARY,
))
let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY);
let adapter = block_on(instance.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
compatible_surface: None,
}))
.ok_or_else(|| {
"This tool requires hardware acceleration, but no compatible graphics device was found."
})?;
let (device, queue) = block_on(adapter.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
let (device, queue) = block_on(adapter.request_device(
&wgpu::DeviceDescriptor {
features: Default::default(),
limits: wgpu::Limits::default(),
shader_validation: false,
},
limits: wgpu::Limits::default(),
}));
None,
))?;
if opt.swf.is_file() {
capture_single_swf(Rc::new(device), Rc::new(queue), &opt)?;

View File

@ -6,7 +6,7 @@ edition = "2018"
license = "MIT OR Apache-2.0"
[dependencies]
wgpu = "0.5"
wgpu = "0.6"
wgpu-native = "0.5"
image = "0.23.8"
jpeg-decoder = "0.1.20"

View File

@ -122,25 +122,26 @@ unsafe impl Zeroable for GPUVertex {}
impl WgpuRenderBackend<SwapChainTarget> {
pub fn for_window<W: HasRawWindowHandle>(window: &W, size: (u32, u32)) -> Result<Self, Error> {
let surface = wgpu::Surface::create(window);
let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY);
let adapter = block_on(wgpu::Adapter::request(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::HighPerformance,
compatible_surface: Some(&surface),
},
wgpu::BackendBit::PRIMARY,
))
let surface = unsafe { instance.create_surface(window) };
let adapter = block_on(instance.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::HighPerformance,
compatible_surface: Some(&surface),
}))
.ok_or_else(|| {
"Ruffle requires hardware acceleration, but no compatible graphics device was found."
})?;
let (device, queue) = block_on(adapter.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
let (device, queue) = block_on(adapter.request_device(
&wgpu::DeviceDescriptor {
features: Default::default(),
limits: wgpu::Limits::default(),
shader_validation: false,
},
limits: wgpu::Limits::default(),
}));
None,
))?;
let target = SwapChainTarget::new(surface, size, &device);
Self::new(Rc::new(device), Rc::new(queue), target)
@ -164,20 +165,18 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
let frame_buffer = device.create_texture(&wgpu::TextureDescriptor {
label: frame_buffer_label.as_deref(),
size: extent,
array_layer_count: 1,
mip_level_count: 1,
sample_count: msaa_sample_count,
dimension: wgpu::TextureDimension::D2,
format: target.format(),
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
});
let frame_buffer_view = frame_buffer.create_default_view();
let frame_buffer_view = frame_buffer.create_view(&Default::default());
let depth_label = create_debug_label!("Depth texture");
let depth_texture = device.create_texture(&wgpu::TextureDescriptor {
label: depth_label.as_deref(),
size: extent,
array_layer_count: 1,
mip_level_count: 1,
sample_count: msaa_sample_count,
dimension: wgpu::TextureDimension::D2,
@ -190,7 +189,7 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
label: register_encoder_label.as_deref(),
});
let depth_texture_view = depth_texture.create_default_view();
let depth_texture_view = depth_texture.create_view(&Default::default());
let (quad_vbo, quad_ibo, quad_tex_transforms) = create_quad_buffers(&device);
@ -234,6 +233,7 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
label: transforms_label.as_deref(),
size: std::mem::size_of::<Transforms>() as u64,
usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
mapped_at_creation: false,
});
let colors_ubo = create_buffer_with_data(
@ -508,7 +508,7 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
}
Some(t) => &t.1,
};
let texture_view = texture.texture.create_default_view();
let texture_view = texture.texture.create_view(&Default::default());
flush_draw(
shape.id,
@ -641,7 +641,6 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
let texture = self.device.create_texture(&wgpu::TextureDescriptor {
label: texture_label.as_deref(),
size: extent,
array_layer_count: 1,
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
@ -649,25 +648,17 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
});
let buffer = create_buffer_with_data(
&self.device,
&data,
wgpu::BufferUsage::COPY_SRC,
create_debug_label!("{} transfer buffer {}", debug_str, id),
);
self.register_encoder.copy_buffer_to_texture(
wgpu::BufferCopyView {
buffer: &buffer,
offset: 0,
bytes_per_row: 4 * extent.width,
rows_per_image: 0,
},
self.queue.write_texture(
wgpu::TextureCopyView {
texture: &texture,
mip_level: 0,
array_layer: 0,
origin: wgpu::Origin3d::ZERO,
origin: Default::default(),
},
&data,
wgpu::TextureDataLayout {
offset: 0,
bytes_per_row: 4 * extent.width,
rows_per_image: 0,
},
extent,
);
@ -744,20 +735,18 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
let bind_group_label = create_debug_label!("Rectangle bind group");
let bind_group = self.device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &self.pipelines.color.bind_layout,
bindings: &[
wgpu::Binding {
entries: &[
wgpu::BindGroupEntry {
binding: 0,
resource: wgpu::BindingResource::Buffer {
buffer: &transforms_ubo,
range: 0..std::mem::size_of::<Transforms>() as u64,
},
resource: wgpu::BindingResource::Buffer(
transforms_ubo.slice(0..std::mem::size_of::<Transforms>() as u64),
),
},
wgpu::Binding {
wgpu::BindGroupEntry {
binding: 1,
resource: wgpu::BindingResource::Buffer {
buffer: &colors_ubo,
range: 0..std::mem::size_of::<ColorAdjustments>() as u64,
},
resource: wgpu::BindingResource::Buffer(
colors_ubo.slice(0..std::mem::size_of::<ColorAdjustments>() as u64),
),
},
],
label: bind_group_label.as_deref(),
@ -771,19 +760,22 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
attachment: color_attachment,
load_op: wgpu::LoadOp::Load,
store_op: wgpu::StoreOp::Store,
clear_color: wgpu::Color::WHITE,
resolve_target,
ops: wgpu::Operations {
load: wgpu::LoadOp::Load,
store: true,
},
}],
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachmentDescriptor {
attachment: &self.depth_texture_view,
depth_load_op: wgpu::LoadOp::Load,
depth_store_op: wgpu::StoreOp::Store,
stencil_load_op: wgpu::LoadOp::Load,
stencil_store_op: wgpu::StoreOp::Store,
clear_depth: 0.0,
clear_stencil: 0,
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Load,
store: true,
}),
stencil_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Load,
store: true,
}),
}),
});
@ -794,8 +786,8 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
self.write_stencil_mask,
));
render_pass.set_bind_group(0, &bind_group, &[]);
render_pass.set_vertex_buffer(0, &self.quad_vbo, 0, 0);
render_pass.set_index_buffer(&self.quad_ibo, 0, 0);
render_pass.set_vertex_buffer(0, self.quad_vbo.slice(..));
render_pass.set_index_buffer(self.quad_ibo.slice(..));
if self.num_masks_active < self.num_masks {
render_pass.set_stencil_reference(self.write_stencil_mask);
@ -823,14 +815,13 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
height,
depth: 1,
},
array_layer_count: 1,
mip_level_count: 1,
sample_count: self.msaa_sample_count,
dimension: wgpu::TextureDimension::D2,
format: self.target.format(),
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
});
self.frame_buffer_view = frame_buffer.create_default_view();
self.frame_buffer_view = frame_buffer.create_view(&Default::default());
let label = create_debug_label!("Depth texture");
let depth_texture = self.device.create_texture(&wgpu::TextureDescriptor {
@ -840,14 +831,13 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
height,
depth: 1,
},
array_layer_count: 1,
mip_level_count: 1,
sample_count: self.msaa_sample_count,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Depth24PlusStencil8,
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
});
self.depth_texture_view = depth_texture.create_default_view();
self.depth_texture_view = depth_texture.create_view(&Default::default());
self.viewport_width = width as f32;
self.viewport_height = height as f32;
@ -936,8 +926,8 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
}),
))
}
Err(wgpu::TimeOut) => {
log::warn!("Couldn't begin new render frame: timed out whilst aquiring new swapchain output");
Err(e) => {
log::warn!("Couldn't begin new render frame: {}", e);
None
}
};
@ -956,24 +946,27 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
attachment: color_attachment,
load_op: wgpu::LoadOp::Clear,
store_op: wgpu::StoreOp::Store,
clear_color: wgpu::Color {
r: f64::from(clear.r) / 255.0,
g: f64::from(clear.g) / 255.0,
b: f64::from(clear.b) / 255.0,
a: f64::from(clear.a) / 255.0,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color {
r: f64::from(clear.r) / 255.0,
g: f64::from(clear.g) / 255.0,
b: f64::from(clear.b) / 255.0,
a: f64::from(clear.a) / 255.0,
}),
store: true,
},
resolve_target,
}],
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachmentDescriptor {
attachment: &self.depth_texture_view,
depth_load_op: wgpu::LoadOp::Clear,
depth_store_op: wgpu::StoreOp::Store,
stencil_load_op: wgpu::LoadOp::Clear,
stencil_store_op: wgpu::StoreOp::Store,
clear_depth: 0.0,
clear_stencil: 0,
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Clear(0.0),
store: true,
}),
stencil_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Clear(0),
store: true,
}),
}),
});
}
@ -1028,8 +1021,10 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
create_debug_label!("Bitmap {} colors transfer buffer", bitmap.0),
);
let texture_view = texture.texture.create_default_view();
let texture_view = texture.texture.create_view(&Default::default());
let sampler_label = create_debug_label!("Bitmap {} sampler", bitmap.0);
let sampler = self.device.create_sampler(&wgpu::SamplerDescriptor {
label: sampler_label.as_deref(),
address_mode_u: wgpu::AddressMode::ClampToEdge,
address_mode_v: wgpu::AddressMode::ClampToEdge,
address_mode_w: wgpu::AddressMode::ClampToEdge,
@ -1038,39 +1033,38 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
mipmap_filter: wgpu::FilterMode::Linear,
lod_min_clamp: 0.0,
lod_max_clamp: 100.0,
compare: wgpu::CompareFunction::Undefined,
compare: None,
anisotropy_clamp: None,
});
let bind_group_label = create_debug_label!("Bitmap {} bind group", bitmap.0);
let bind_group = self.device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &self.pipelines.bitmap.bind_layout,
bindings: &[
wgpu::Binding {
entries: &[
wgpu::BindGroupEntry {
binding: 0,
resource: wgpu::BindingResource::Buffer {
buffer: &transforms_ubo,
range: 0..std::mem::size_of::<Transforms>() as u64,
},
resource: wgpu::BindingResource::Buffer(
transforms_ubo.slice(0..std::mem::size_of::<Transforms>() as u64),
),
},
wgpu::Binding {
wgpu::BindGroupEntry {
binding: 1,
resource: wgpu::BindingResource::Buffer {
buffer: &self.quad_tex_transforms,
range: 0..std::mem::size_of::<TextureTransforms>() as u64,
},
resource: wgpu::BindingResource::Buffer(
self.quad_tex_transforms
.slice(0..std::mem::size_of::<TextureTransforms>() as u64),
),
},
wgpu::Binding {
wgpu::BindGroupEntry {
binding: 2,
resource: wgpu::BindingResource::Buffer {
buffer: &colors_ubo,
range: 0..std::mem::size_of::<ColorAdjustments>() as u64,
},
resource: wgpu::BindingResource::Buffer(
colors_ubo.slice(0..std::mem::size_of::<ColorAdjustments>() as u64),
),
},
wgpu::Binding {
wgpu::BindGroupEntry {
binding: 3,
resource: wgpu::BindingResource::TextureView(&texture_view),
},
wgpu::Binding {
wgpu::BindGroupEntry {
binding: 4,
resource: wgpu::BindingResource::Sampler(&sampler),
},
@ -1086,19 +1080,22 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
attachment: color_attachment,
load_op: wgpu::LoadOp::Load,
store_op: wgpu::StoreOp::Store,
clear_color: wgpu::Color::WHITE,
resolve_target,
ops: wgpu::Operations {
load: wgpu::LoadOp::Load,
store: true,
},
}],
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachmentDescriptor {
attachment: &self.depth_texture_view,
depth_load_op: wgpu::LoadOp::Load,
depth_store_op: wgpu::StoreOp::Store,
stencil_load_op: wgpu::LoadOp::Load,
stencil_store_op: wgpu::StoreOp::Store,
clear_depth: 0.0,
clear_stencil: 0,
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Load,
store: true,
}),
stencil_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Load,
store: true,
}),
}),
});
@ -1109,8 +1106,8 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
self.write_stencil_mask,
));
render_pass.set_bind_group(0, &bind_group, &[]);
render_pass.set_vertex_buffer(0, &self.quad_vbo, 0, 0);
render_pass.set_index_buffer(&self.quad_ibo, 0, 0);
render_pass.set_vertex_buffer(0, self.quad_vbo.slice(..));
render_pass.set_index_buffer(self.quad_ibo.slice(..));
if self.num_masks_active < self.num_masks {
render_pass.set_stencil_reference(self.write_stencil_mask);
@ -1189,19 +1186,22 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
attachment: color_attachment,
load_op: wgpu::LoadOp::Load,
store_op: wgpu::StoreOp::Store,
clear_color: wgpu::Color::WHITE,
resolve_target,
ops: wgpu::Operations {
load: wgpu::LoadOp::Load,
store: true,
},
}],
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachmentDescriptor {
attachment: &self.depth_texture_view,
depth_load_op: wgpu::LoadOp::Load,
depth_store_op: wgpu::StoreOp::Store,
stencil_load_op: wgpu::LoadOp::Load,
stencil_store_op: wgpu::StoreOp::Store,
clear_depth: 0.0,
clear_stencil: 0,
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Load,
store: true,
}),
stencil_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Load,
store: true,
}),
}),
});
@ -1234,8 +1234,8 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
}
render_pass.set_bind_group(0, &draw.bind_group, &[]);
render_pass.set_vertex_buffer(0, &draw.vertex_buffer, 0, 0);
render_pass.set_index_buffer(&draw.index_buffer, 0, 0);
render_pass.set_vertex_buffer(0, draw.vertex_buffer.slice(..));
render_pass.set_index_buffer(draw.index_buffer.slice(..));
if self.num_masks_active < self.num_masks {
render_pass.set_stencil_reference(self.write_stencil_mask);
@ -1260,7 +1260,7 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
self.target.submit(
&self.device,
&self.queue,
&[register_buffer, encoder.finish()],
vec![register_buffer, encoder.finish()],
);
}
}
@ -1345,20 +1345,23 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
attachment: color_attachment,
load_op: wgpu::LoadOp::Load,
store_op: wgpu::StoreOp::Store,
clear_color: wgpu::Color::WHITE,
resolve_target,
ops: wgpu::Operations {
load: wgpu::LoadOp::Load,
store: true,
},
}],
depth_stencil_attachment: Some(
wgpu::RenderPassDepthStencilAttachmentDescriptor {
attachment: &self.depth_texture_view,
depth_load_op: wgpu::LoadOp::Load,
depth_store_op: wgpu::StoreOp::Store,
stencil_load_op: wgpu::LoadOp::Clear,
stencil_store_op: wgpu::StoreOp::Store,
clear_depth: 0.0,
clear_stencil: self.test_stencil_mask,
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Load,
store: true,
}),
stencil_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Clear(self.test_stencil_mask),
store: true,
}),
},
),
});

View File

@ -33,35 +33,47 @@ impl ShapePipeline {
impl Pipelines {
pub fn new(device: &wgpu::Device, msaa_sample_count: u32) -> Result<Self, Error> {
let color_vs_bytes = include_bytes!("../shaders/color.vert.spv");
let color_vs = device.create_shader_module(&wgpu::read_spirv(std::io::Cursor::new(
&color_vs_bytes[..],
))?);
let color_fs_bytes = include_bytes!("../shaders/color.frag.spv");
let color_fs = device.create_shader_module(&wgpu::read_spirv(std::io::Cursor::new(
&color_fs_bytes[..],
))?);
let texture_vs_bytes = include_bytes!("../shaders/texture.vert.spv");
let texture_vs = device.create_shader_module(&wgpu::read_spirv(std::io::Cursor::new(
&texture_vs_bytes[..],
))?);
let gradient_fs_bytes = include_bytes!("../shaders/gradient.frag.spv");
let gradient_fs = device.create_shader_module(&wgpu::read_spirv(std::io::Cursor::new(
&gradient_fs_bytes[..],
))?);
let bitmap_fs_bytes = include_bytes!("../shaders/bitmap.frag.spv");
let bitmap_fs = device.create_shader_module(&wgpu::read_spirv(std::io::Cursor::new(
&bitmap_fs_bytes[..],
))?);
let color_vs =
device.create_shader_module(wgpu::include_spirv!("../shaders/color.vert.spv"));
let color_fs =
device.create_shader_module(wgpu::include_spirv!("../shaders/color.frag.spv"));
let texture_vs =
device.create_shader_module(wgpu::include_spirv!("../shaders/texture.vert.spv"));
let gradient_fs =
device.create_shader_module(wgpu::include_spirv!("../shaders/gradient.frag.spv"));
let bitmap_fs =
device.create_shader_module(wgpu::include_spirv!("../shaders/bitmap.frag.spv"));
let vertex_buffers_description = [wgpu::VertexBufferDescriptor {
stride: std::mem::size_of::<GPUVertex>() as u64,
step_mode: wgpu::InputStepMode::Vertex,
attributes: &vertex_attr_array![
0 => Float2,
1 => Float4
],
}];
Ok(Self {
color: create_color_pipelines(&device, &color_vs, &color_fs, msaa_sample_count),
bitmap: create_bitmap_pipeline(&device, &texture_vs, &bitmap_fs, msaa_sample_count),
color: create_color_pipelines(
&device,
&color_vs,
&color_fs,
msaa_sample_count,
&vertex_buffers_description,
),
bitmap: create_bitmap_pipeline(
&device,
&texture_vs,
&bitmap_fs,
msaa_sample_count,
&vertex_buffers_description,
),
gradient: create_gradient_pipeline(
&device,
&texture_vs,
&gradient_fs,
msaa_sample_count,
&vertex_buffers_description,
),
})
}
@ -73,10 +85,12 @@ fn create_pipeline_descriptor<'a>(
pipeline_layout: &'a wgpu::PipelineLayout,
depth_stencil_state: Option<wgpu::DepthStencilStateDescriptor>,
color_states: &'a [wgpu::ColorStateDescriptor],
vertex_buffers_description: &'a [wgpu::VertexBufferDescriptor<'a>],
msaa_sample_count: u32,
) -> wgpu::RenderPipelineDescriptor<'a> {
wgpu::RenderPipelineDescriptor {
layout: &pipeline_layout,
label: None,
layout: Some(&pipeline_layout),
vertex_stage: wgpu::ProgrammableStageDescriptor {
module: &vertex_shader,
entry_point: "main",
@ -88,6 +102,7 @@ fn create_pipeline_descriptor<'a>(
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
front_face: wgpu::FrontFace::Ccw,
cull_mode: wgpu::CullMode::None,
clamp_depth: false,
depth_bias: 0,
depth_bias_slope_scale: 0.0,
depth_bias_clamp: 0.0,
@ -100,14 +115,7 @@ fn create_pipeline_descriptor<'a>(
alpha_to_coverage_enabled: false,
vertex_state: wgpu::VertexStateDescriptor {
index_format: wgpu::IndexFormat::Uint16,
vertex_buffers: &[wgpu::VertexBufferDescriptor {
stride: std::mem::size_of::<GPUVertex>() as u64,
step_mode: wgpu::InputStepMode::Vertex,
attributes: &vertex_attr_array![
0 => Float2,
1 => Float4
],
}],
vertex_buffers: vertex_buffers_description,
},
}
}
@ -117,26 +125,37 @@ fn create_color_pipelines(
vertex_shader: &wgpu::ShaderModule,
fragment_shader: &wgpu::ShaderModule,
msaa_sample_count: u32,
vertex_buffers_description: &[wgpu::VertexBufferDescriptor<'_>],
) -> ShapePipeline {
let label = create_debug_label!("Color shape bind group");
let bind_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
bindings: &[
entries: &[
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX,
ty: wgpu::BindingType::UniformBuffer { dynamic: false },
ty: wgpu::BindingType::UniformBuffer {
dynamic: false,
min_binding_size: None,
},
count: None,
},
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::VERTEX,
ty: wgpu::BindingType::UniformBuffer { dynamic: false },
ty: wgpu::BindingType::UniformBuffer {
dynamic: false,
min_binding_size: None,
},
count: None,
},
],
label: label.as_deref(),
});
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: None,
bind_group_layouts: &[&bind_layout],
push_constant_ranges: &[],
});
let mut write_mask_pipelines = Vec::new();
@ -151,20 +170,22 @@ fn create_color_pipelines(
format: wgpu::TextureFormat::Depth24PlusStencil8,
depth_write_enabled: true,
depth_compare: wgpu::CompareFunction::Always,
stencil_front: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Always,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Replace,
stencil: wgpu::StencilStateDescriptor {
front: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Always,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Replace,
},
back: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Always,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Replace,
},
read_mask: 0,
write_mask: 1 << i,
},
stencil_back: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Always,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Replace,
},
stencil_read_mask: 0,
stencil_write_mask: 1 << i,
}),
&[wgpu::ColorStateDescriptor {
format: wgpu::TextureFormat::Bgra8Unorm,
@ -180,6 +201,7 @@ fn create_color_pipelines(
},
write_mask: wgpu::ColorWrite::empty(),
}],
vertex_buffers_description,
msaa_sample_count,
)));
}
@ -193,20 +215,22 @@ fn create_color_pipelines(
format: wgpu::TextureFormat::Depth24PlusStencil8,
depth_write_enabled: true,
depth_compare: wgpu::CompareFunction::Always,
stencil_front: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Equal,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Keep,
stencil: wgpu::StencilStateDescriptor {
front: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Equal,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Keep,
},
back: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Equal,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Keep,
},
read_mask: i,
write_mask: 0,
},
stencil_back: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Equal,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Keep,
},
stencil_read_mask: i,
stencil_write_mask: 0,
}),
&[wgpu::ColorStateDescriptor {
format: wgpu::TextureFormat::Bgra8Unorm,
@ -222,6 +246,7 @@ fn create_color_pipelines(
},
write_mask: wgpu::ColorWrite::ALL,
}],
vertex_buffers_description,
msaa_sample_count,
)));
}
@ -238,24 +263,37 @@ fn create_bitmap_pipeline(
vertex_shader: &wgpu::ShaderModule,
fragment_shader: &wgpu::ShaderModule,
msaa_sample_count: u32,
vertex_buffers_description: &[wgpu::VertexBufferDescriptor<'_>],
) -> ShapePipeline {
let label = create_debug_label!("Bitmap shape bind group");
let bind_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
bindings: &[
entries: &[
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX,
ty: wgpu::BindingType::UniformBuffer { dynamic: false },
ty: wgpu::BindingType::UniformBuffer {
dynamic: false,
min_binding_size: None,
},
count: None,
},
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::VERTEX,
ty: wgpu::BindingType::UniformBuffer { dynamic: false },
ty: wgpu::BindingType::UniformBuffer {
dynamic: false,
min_binding_size: None,
},
count: None,
},
wgpu::BindGroupLayoutEntry {
binding: 2,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::UniformBuffer { dynamic: false },
ty: wgpu::BindingType::UniformBuffer {
dynamic: false,
min_binding_size: None,
},
count: None,
},
wgpu::BindGroupLayoutEntry {
binding: 3,
@ -265,18 +303,22 @@ fn create_bitmap_pipeline(
component_type: wgpu::TextureComponentType::Float,
dimension: wgpu::TextureViewDimension::D2,
},
count: None,
},
wgpu::BindGroupLayoutEntry {
binding: 4,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler { comparison: false },
count: None,
},
],
label: label.as_deref(),
});
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: None,
bind_group_layouts: &[&bind_layout],
push_constant_ranges: &[],
});
let mut write_mask_pipelines = Vec::new();
@ -291,20 +333,22 @@ fn create_bitmap_pipeline(
format: wgpu::TextureFormat::Depth24PlusStencil8,
depth_write_enabled: true,
depth_compare: wgpu::CompareFunction::Always,
stencil_front: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Always,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Replace,
stencil: wgpu::StencilStateDescriptor {
front: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Always,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Replace,
},
back: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Always,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Replace,
},
read_mask: 0,
write_mask: 1 << i,
},
stencil_back: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Always,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Replace,
},
stencil_read_mask: 0,
stencil_write_mask: 1 << i,
}),
&[wgpu::ColorStateDescriptor {
format: wgpu::TextureFormat::Bgra8Unorm,
@ -320,6 +364,7 @@ fn create_bitmap_pipeline(
},
write_mask: wgpu::ColorWrite::empty(),
}],
vertex_buffers_description,
msaa_sample_count,
)));
}
@ -333,20 +378,22 @@ fn create_bitmap_pipeline(
format: wgpu::TextureFormat::Depth24PlusStencil8,
depth_write_enabled: true,
depth_compare: wgpu::CompareFunction::Always,
stencil_front: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Equal,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Keep,
stencil: wgpu::StencilStateDescriptor {
front: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Equal,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Keep,
},
back: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Equal,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Keep,
},
read_mask: i,
write_mask: 0,
},
stencil_back: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Equal,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Keep,
},
stencil_read_mask: i,
stencil_write_mask: 0,
}),
&[wgpu::ColorStateDescriptor {
format: wgpu::TextureFormat::Bgra8Unorm,
@ -362,6 +409,7 @@ fn create_bitmap_pipeline(
},
write_mask: wgpu::ColorWrite::ALL,
}],
vertex_buffers_description,
msaa_sample_count,
)));
}
@ -378,39 +426,56 @@ fn create_gradient_pipeline(
vertex_shader: &wgpu::ShaderModule,
fragment_shader: &wgpu::ShaderModule,
msaa_sample_count: u32,
vertex_buffers_description: &[wgpu::VertexBufferDescriptor<'_>],
) -> ShapePipeline {
let label = create_debug_label!("Gradient shape bind group");
let bind_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
bindings: &[
entries: &[
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX,
ty: wgpu::BindingType::UniformBuffer { dynamic: false },
ty: wgpu::BindingType::UniformBuffer {
dynamic: false,
min_binding_size: None,
},
count: None,
},
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::VERTEX,
ty: wgpu::BindingType::UniformBuffer { dynamic: false },
ty: wgpu::BindingType::UniformBuffer {
dynamic: false,
min_binding_size: None,
},
count: None,
},
wgpu::BindGroupLayoutEntry {
binding: 2,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::UniformBuffer { dynamic: false },
ty: wgpu::BindingType::UniformBuffer {
dynamic: false,
min_binding_size: None,
},
count: None,
},
wgpu::BindGroupLayoutEntry {
binding: 3,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::StorageBuffer {
dynamic: false,
min_binding_size: None,
readonly: true,
},
count: None,
},
],
label: label.as_deref(),
});
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: None,
bind_group_layouts: &[&bind_layout],
push_constant_ranges: &[],
});
let mut write_mask_pipelines = Vec::new();
@ -425,20 +490,22 @@ fn create_gradient_pipeline(
format: wgpu::TextureFormat::Depth24PlusStencil8,
depth_write_enabled: true,
depth_compare: wgpu::CompareFunction::Always,
stencil_front: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Always,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Replace,
stencil: wgpu::StencilStateDescriptor {
front: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Always,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Replace,
},
back: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Always,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Replace,
},
read_mask: 0,
write_mask: 1 << i,
},
stencil_back: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Always,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Replace,
},
stencil_read_mask: 0,
stencil_write_mask: 1 << i,
}),
&[wgpu::ColorStateDescriptor {
format: wgpu::TextureFormat::Bgra8Unorm,
@ -454,6 +521,7 @@ fn create_gradient_pipeline(
},
write_mask: wgpu::ColorWrite::empty(),
}],
vertex_buffers_description,
msaa_sample_count,
)));
}
@ -467,20 +535,22 @@ fn create_gradient_pipeline(
format: wgpu::TextureFormat::Depth24PlusStencil8,
depth_write_enabled: true,
depth_compare: wgpu::CompareFunction::Always,
stencil_front: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Equal,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Keep,
stencil: wgpu::StencilStateDescriptor {
front: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Equal,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Keep,
},
back: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Equal,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Keep,
},
read_mask: i,
write_mask: 0,
},
stencil_back: wgpu::StencilStateFaceDescriptor {
compare: wgpu::CompareFunction::Equal,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Keep,
},
stencil_read_mask: i,
stencil_write_mask: 0,
}),
&[wgpu::ColorStateDescriptor {
format: wgpu::TextureFormat::Bgra8Unorm,
@ -496,6 +566,7 @@ fn create_gradient_pipeline(
},
write_mask: wgpu::ColorWrite::ALL,
}],
vertex_buffers_description,
msaa_sample_count,
)));
}

View File

@ -97,20 +97,18 @@ impl IncompleteDrawType {
create_debug_label!("Shape {} (color) draw {} bindgroup", shape_id, draw_id);
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &pipelines.color.bind_layout,
bindings: &[
wgpu::Binding {
entries: &[
wgpu::BindGroupEntry {
binding: 0,
resource: wgpu::BindingResource::Buffer {
buffer: transforms_ubo,
range: 0..std::mem::size_of::<Transforms>() as u64,
},
resource: wgpu::BindingResource::Buffer(
transforms_ubo.slice(0..std::mem::size_of::<Transforms>() as u64),
),
},
wgpu::Binding {
wgpu::BindGroupEntry {
binding: 1,
resource: wgpu::BindingResource::Buffer {
buffer: colors_ubo,
range: 0..std::mem::size_of::<ColorAdjustments>() as u64,
},
resource: wgpu::BindingResource::Buffer(
colors_ubo.slice(0..std::mem::size_of::<ColorAdjustments>() as u64),
),
},
],
label: bind_group_label.as_deref(),
@ -142,7 +140,7 @@ impl IncompleteDrawType {
let gradient_ubo = create_buffer_with_data(
device,
bytemuck::cast_slice(&[gradient]),
wgpu::BufferUsage::STORAGE_READ,
wgpu::BufferUsage::STORAGE,
create_debug_label!(
"Shape {} draw {} gradient ubo transfer buffer",
shape_id,
@ -154,34 +152,32 @@ impl IncompleteDrawType {
create_debug_label!("Shape {} (gradient) draw {} bindgroup", shape_id, draw_id);
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &pipelines.gradient.bind_layout,
bindings: &[
wgpu::Binding {
entries: &[
wgpu::BindGroupEntry {
binding: 0,
resource: wgpu::BindingResource::Buffer {
buffer: transforms_ubo,
range: 0..std::mem::size_of::<Transforms>() as u64,
},
resource: wgpu::BindingResource::Buffer(
transforms_ubo.slice(0..std::mem::size_of::<Transforms>() as u64),
),
},
wgpu::Binding {
wgpu::BindGroupEntry {
binding: 1,
resource: wgpu::BindingResource::Buffer {
buffer: &tex_transforms_ubo,
range: 0..std::mem::size_of::<TextureTransforms>() as u64,
},
resource: wgpu::BindingResource::Buffer(
tex_transforms_ubo
.slice(0..std::mem::size_of::<TextureTransforms>() as u64),
),
},
wgpu::Binding {
wgpu::BindGroupEntry {
binding: 2,
resource: wgpu::BindingResource::Buffer {
buffer: colors_ubo,
range: 0..std::mem::size_of::<ColorAdjustments>() as u64,
},
resource: wgpu::BindingResource::Buffer(
colors_ubo.slice(0..std::mem::size_of::<ColorAdjustments>() as u64),
),
},
wgpu::Binding {
wgpu::BindGroupEntry {
binding: 3,
resource: wgpu::BindingResource::Buffer {
buffer: &gradient_ubo,
range: 0..std::mem::size_of::<GradientUniforms>() as u64,
},
resource: wgpu::BindingResource::Buffer(
gradient_ubo
.slice(0..std::mem::size_of::<GradientUniforms>() as u64),
),
},
],
label: bind_group_label.as_deref(),
@ -229,6 +225,7 @@ impl IncompleteDrawType {
};
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
label: None,
address_mode_u: address_mode,
address_mode_v: address_mode,
address_mode_w: address_mode,
@ -237,40 +234,39 @@ impl IncompleteDrawType {
mipmap_filter: filter,
lod_min_clamp: 0.0,
lod_max_clamp: 100.0,
compare: wgpu::CompareFunction::Undefined,
compare: None,
anisotropy_clamp: None,
});
let bind_group_label =
create_debug_label!("Shape {} (bitmap) draw {} bindgroup", shape_id, draw_id);
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &pipelines.bitmap.bind_layout,
bindings: &[
wgpu::Binding {
entries: &[
wgpu::BindGroupEntry {
binding: 0,
resource: wgpu::BindingResource::Buffer {
buffer: transforms_ubo,
range: 0..std::mem::size_of::<Transforms>() as u64,
},
resource: wgpu::BindingResource::Buffer(
transforms_ubo.slice(0..std::mem::size_of::<Transforms>() as u64),
),
},
wgpu::Binding {
wgpu::BindGroupEntry {
binding: 1,
resource: wgpu::BindingResource::Buffer {
buffer: &tex_transforms_ubo,
range: 0..std::mem::size_of::<TextureTransforms>() as u64,
},
resource: wgpu::BindingResource::Buffer(
tex_transforms_ubo
.slice(0..std::mem::size_of::<TextureTransforms>() as u64),
),
},
wgpu::Binding {
wgpu::BindGroupEntry {
binding: 2,
resource: wgpu::BindingResource::Buffer {
buffer: colors_ubo,
range: 0..std::mem::size_of::<ColorAdjustments>() as u64,
},
resource: wgpu::BindingResource::Buffer(
colors_ubo.slice(0..std::mem::size_of::<ColorAdjustments>() as u64),
),
},
wgpu::Binding {
wgpu::BindGroupEntry {
binding: 3,
resource: wgpu::BindingResource::TextureView(&texture_view),
},
wgpu::Binding {
wgpu::BindGroupEntry {
binding: 4,
resource: wgpu::BindingResource::Sampler(&sampler),
},

View File

@ -1,3 +1,4 @@
use crate::utils::BufferDimensions;
use futures::executor::block_on;
use image::buffer::ConvertBuffer;
use image::{Bgra, ImageBuffer, RgbaImage};
@ -18,13 +19,13 @@ pub trait RenderTarget: Debug + 'static {
fn height(&self) -> u32;
fn get_next_texture(&mut self) -> Result<Self::Frame, wgpu::TimeOut>;
fn get_next_texture(&mut self) -> Result<Self::Frame, wgpu::SwapChainError>;
fn submit(
fn submit<I: IntoIterator<Item = wgpu::CommandBuffer>>(
&self,
device: &wgpu::Device,
queue: &wgpu::Queue,
command_buffers: &[wgpu::CommandBuffer],
command_buffers: I,
);
}
@ -36,11 +37,11 @@ pub struct SwapChainTarget {
}
#[derive(Debug)]
pub struct SwapChainTargetFrame(wgpu::SwapChainOutput);
pub struct SwapChainTargetFrame(wgpu::SwapChainFrame);
impl RenderTargetFrame for SwapChainTargetFrame {
fn view(&self) -> &wgpu::TextureView {
&self.0.view
&self.0.output.view
}
}
@ -83,15 +84,17 @@ impl RenderTarget for SwapChainTarget {
self.swap_chain_desc.height
}
fn get_next_texture(&mut self) -> Result<Self::Frame, wgpu::TimeOut> {
self.swap_chain.get_next_texture().map(SwapChainTargetFrame)
fn get_next_texture(&mut self) -> Result<Self::Frame, wgpu::SwapChainError> {
self.swap_chain
.get_current_frame()
.map(SwapChainTargetFrame)
}
fn submit(
fn submit<I: IntoIterator<Item = wgpu::CommandBuffer>>(
&self,
_device: &wgpu::Device,
queue: &wgpu::Queue,
command_buffers: &[wgpu::CommandBuffer],
command_buffers: I,
) {
queue.submit(command_buffers);
}
@ -103,6 +106,7 @@ pub struct TextureTarget {
texture: wgpu::Texture,
format: wgpu::TextureFormat,
buffer: wgpu::Buffer,
buffer_dimensions: BufferDimensions,
}
#[derive(Debug)]
@ -118,6 +122,7 @@ impl RenderTargetFrame for TextureTargetFrame {
impl TextureTarget {
pub fn new(device: &wgpu::Device, size: (u32, u32)) -> Self {
let buffer_dimensions = BufferDimensions::new(size.0 as usize, size.1 as usize);
let size = wgpu::Extent3d {
width: size.0,
height: size.1,
@ -128,7 +133,6 @@ impl TextureTarget {
let texture = device.create_texture(&wgpu::TextureDescriptor {
label: texture_label.as_deref(),
size,
array_layer_count: 1,
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
@ -138,29 +142,35 @@ impl TextureTarget {
let buffer_label = create_debug_label!("Render target buffer");
let buffer = device.create_buffer(&wgpu::BufferDescriptor {
label: buffer_label.as_deref(),
size: size.width as u64 * size.height as u64 * 4,
size: (buffer_dimensions.padded_bytes_per_row * buffer_dimensions.height) as u64,
usage: wgpu::BufferUsage::COPY_DST | wgpu::BufferUsage::MAP_READ,
mapped_at_creation: false,
});
Self {
size,
texture,
format,
buffer,
buffer_dimensions,
}
}
pub fn capture(&self, device: &wgpu::Device) -> Option<RgbaImage> {
let buffer_future = self
.buffer
.map_read(0, self.size.width as u64 * self.size.height as u64 * 4);
let buffer_future = self.buffer.slice(..).map_async(wgpu::MapMode::Read);
device.poll(wgpu::Maintain::Wait);
match block_on(buffer_future) {
Ok(map) => {
let bgra = BgraImage::from_raw(
self.size.width,
self.size.height,
Vec::from(map.as_slice()),
Ok(()) => {
let map = self.buffer.slice(..).get_mapped_range();
let mut buffer = Vec::with_capacity(
self.buffer_dimensions.height * self.buffer_dimensions.unpadded_bytes_per_row,
);
for chunk in map.chunks(self.buffer_dimensions.padded_bytes_per_row) {
buffer
.extend_from_slice(&chunk[..self.buffer_dimensions.unpadded_bytes_per_row]);
}
let bgra = BgraImage::from_raw(self.size.width, self.size.height, buffer);
bgra.map(|image| image.convert())
}
Err(e) => {
@ -182,7 +192,6 @@ impl RenderTarget for TextureTarget {
self.texture = device.create_texture(&wgpu::TextureDescriptor {
label: label.as_deref(),
size: self.size,
array_layer_count: 1,
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
@ -195,6 +204,7 @@ impl RenderTarget for TextureTarget {
label: buffer_label.as_deref(),
size: width as u64 * height as u64 * 4,
usage: wgpu::BufferUsage::COPY_DST | wgpu::BufferUsage::MAP_READ,
mapped_at_creation: false,
});
}
@ -210,15 +220,17 @@ impl RenderTarget for TextureTarget {
self.size.height
}
fn get_next_texture(&mut self) -> Result<Self::Frame, wgpu::TimeOut> {
Ok(TextureTargetFrame(self.texture.create_default_view()))
fn get_next_texture(&mut self) -> Result<Self::Frame, wgpu::SwapChainError> {
Ok(TextureTargetFrame(
self.texture.create_view(&Default::default()),
))
}
fn submit(
fn submit<I: IntoIterator<Item = wgpu::CommandBuffer>>(
&self,
device: &wgpu::Device,
queue: &wgpu::Queue,
command_buffers: &[wgpu::CommandBuffer],
command_buffers: I,
) {
let label = create_debug_label!("Render target transfer encoder");
let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
@ -228,18 +240,18 @@ impl RenderTarget for TextureTarget {
wgpu::TextureCopyView {
texture: &self.texture,
mip_level: 0,
array_layer: 0,
origin: wgpu::Origin3d::ZERO,
},
wgpu::BufferCopyView {
buffer: &self.buffer,
offset: 0,
bytes_per_row: self.width() * 4,
rows_per_image: 0,
layout: wgpu::TextureDataLayout {
offset: 0,
bytes_per_row: self.buffer_dimensions.padded_bytes_per_row as u32,
rows_per_image: 0,
},
},
self.size,
);
queue.submit(command_buffers);
queue.submit(&[encoder.finish()]);
queue.submit(command_buffers.into_iter().chain(Some(encoder.finish())));
}
}

View File

@ -1,7 +1,9 @@
use lyon::lyon_algorithms::path::Path;
use ruffle_core::shape_utils::DrawCommand;
use ruffle_core::swf;
use std::mem::size_of;
use swf::{GradientSpread, Twips};
use wgpu::util::DeviceExt;
macro_rules! create_debug_label {
($($arg:tt)*) => (
if cfg!(feature = "render_debug_labels") {
@ -18,13 +20,11 @@ pub fn create_buffer_with_data(
usage: wgpu::BufferUsage,
label: Option<String>,
) -> wgpu::Buffer {
let mapped = device.create_buffer_mapped(&wgpu::BufferDescriptor {
size: data.len() as u64,
device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
usage,
label: label.as_deref(),
});
mapped.data.copy_from_slice(data);
mapped.finish()
contents: data,
})
}
pub fn point(x: Twips, y: Twips) -> lyon::math::Point {
@ -146,3 +146,28 @@ pub fn gradient_spread_mode_index(spread: GradientSpread) -> i32 {
GradientSpread::Reflect => 2,
}
}
// Based off wgpu example 'capture'
#[derive(Debug)]
pub struct BufferDimensions {
pub width: usize,
pub height: usize,
pub unpadded_bytes_per_row: usize,
pub padded_bytes_per_row: usize,
}
impl BufferDimensions {
pub fn new(width: usize, height: usize) -> Self {
let bytes_per_pixel = size_of::<u32>();
let unpadded_bytes_per_row = width * bytes_per_pixel;
let align = wgpu::COPY_BYTES_PER_ROW_ALIGNMENT as usize;
let padded_bytes_per_row_padding = (align - unpadded_bytes_per_row % align) % align;
let padded_bytes_per_row = unpadded_bytes_per_row + padded_bytes_per_row_padding;
Self {
width,
height,
unpadded_bytes_per_row,
padded_bytes_per_row,
}
}
}