update to wgpu 0.18

This commit is contained in:
João Capucho 2021-08-17 23:15:29 +01:00 committed by Isse
parent 5e987efe99
commit d29d22dd0a
48 changed files with 1281 additions and 1108 deletions

858
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
cargo-features = ["named-profiles","profile-overrides"]
cargo-features = ["named-profiles", "profile-overrides"]
[workspace]
resolver = "2"
@ -51,13 +51,13 @@ opt-level = 3
# this profile is used by developers if dev doesn't has enough debug information,
# the name must != debug, as debug is used by dev because....
[profile.debuginfo]
inherits= 'dev'
inherits = 'dev'
debug = true
# used to perform things that do a *lot* of math (i.e. worldgen) but still need reasonable compilation time. Ideally this would also
# add -C target-cpu=native, but I don't think you can set this by profile currently.
[profile.no_overflow]
inherits= 'dev'
inherits = 'dev'
overflow-checks = false
debug-assertions = false
@ -80,7 +80,7 @@ overflow-checks = false
debug-assertions = false
lto = true
debug = false
panic = "abort" # don't need unwinding so we can skip including the landing pads for that
panic = "abort" # don't need unwinding so we can skip including the landing pads for that
# line tables so we can have useful backtraces for in-house crates
[profile.release.package."veloren-network"]
debug = 1
@ -108,7 +108,7 @@ incremental = true
# this profile is used by developers for release profiling
[profile.releasedebuginfo]
inherits = 'release'
inherits = 'release'
debug = 1
[workspace.metadata.nix]
@ -159,11 +159,6 @@ clap = { version = "4.2", features = ["derive"]}
[patch.crates-io]
vek = { git = "https://github.com/yoanlcq/vek.git", rev = "84d5cb65841d46599a986c5477341bea4456be26" }
# patch winit to support older raw-window-handle that works with old wgpu
winit = { git = "https://github.com/Imberflur/winit.git", tag = "raw-window-handle-0.4-retro-support-v1" }
# patch wgpu so we can use wgpu-profiler crate
# wgpu = { git = "https://github.com/gfx-rs/wgpu.git", rev = "a92b8549a8e2cb9dac781bafc5ed32828f3caf46" }
wgpu = { git = "https://github.com/pythonesque/wgpu.git", rev = "179ea209374a92837cde252f1d9ee01f628cae08" }
# ntapi 3.7 fails to compile under windows due to the bug https://github.com/MSxDOS/ntapi/pull/12
ntapi = { git = "https://github.com/MSxDOS/ntapi.git", rev = "9f56b149c9e25796739157c0fce3e0007a7de6eb" }
shred = { git = "https://github.com/amethyst/shred.git", rev = "5d52c6fc390dd04c12158633e77591f6523d1f85" }
@ -187,21 +182,17 @@ gfx-backend-metal = { git = "https://github.com/Imberflur/gfx.git", tag = "velor
# gfx-backend-dx12 = { git = "https://github.com/gfx-rs/gfx.git", rev = "e305dcca3557923a6a8810162d8dd09cb45a43a6" }
# gfx-backend-dx11 = { git = "https://github.com/gfx-rs/gfx.git", rev = "e305dcca3557923a6a8810162d8dd09cb45a43a6" }
# gfx-backend-metal = { git = "https://github.com/gfx-rs/gfx.git", rev = "e305dcca3557923a6a8810162d8dd09cb45a43a6" }
# keyboard-keynames = { git = "https://gitlab.com/Capucho/keyboard-keynames.git", rev = "7b1375ee4ea01d0e0b80c419cb27f0498e67df3a" }
# naga = { path = "../naga" }
# # Uncomment this to use a local fork of winit (for testing purposes)
# winit = { path = "../winit" }
# # Uncomment this to use a local fork of wgpu (for testing purposes)
# [patch.'https://github.com/gfx-rs/wgpu']
# wgpu-hal = { path = "../wgpu/wgpu-hal" }
# wgpu-core = { path = "../wgpu/wgpu-core" }
# wgpu-types = { path = "../wgpu/wgpu-types" }
# # Uncomment this to use a local fork of gfx-hal (for testing purposes)
# [patch."https://github.com/gfx-rs/gfx"]
# gfx-hal = { path = "../gfx/src/hal" }
# gfx-backend-empty = { path = "../gfx/src/backend/empty" }
# gfx-backend-vulkan = { path = "../gfx/src/backend/vulkan" }
# gfx-backend-gl = { path = "../gfx/src/backend/gl" }
# gfx-backend-dx12 = { path = "../gfx/src/backend/dx12" }
# gfx-backend-dx11 = { path = "../gfx/src/backend/dx11" }
# gfx-backend-metal = { path = "../gfx/src/backend/metal" }
[patch."https://github.com/gfx-rs/naga"]
# naga = { path = "../naga" }

View File

@ -127,6 +127,8 @@
export VELOREN_GIT_VERSION="${git.prettyRev}"
export VELOREN_GIT_TAG="${git.tag}"
'';
VK_ADD_LAYER_PATH = "${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d";
});
nci.projects."veloren" = {
@ -180,6 +182,8 @@
libxkbcommon
udev
xorg.libxcb
fontconfig
];
nativeBuildInputs = with pkgs; [
python3

View File

@ -57,9 +57,9 @@ voxygen-egui = {package = "veloren-voxygen-egui", path = "egui", optional = true
# Graphics
winit = {version = "0.28.6", features = ["serde"]}
wgpu = { version = "=0.8.0", features = ["trace", "cross"] }
wgpu-profiler = { git = "https://github.com/Imberflur/wgpu-profiler", tag = "wgpu-0.8" }
bytemuck = { version="1.4", features=["derive"] }
wgpu = { version = "=0.18.0", features = ["trace", "spirv", "glsl"] }
wgpu-profiler = "0.15.0"
bytemuck = { version="1.7", features=["derive"] }
# shaderc = "0.8.0"
# Working around a current bug in shaderc that causes it to use the system installation even if we specify compile from source
shaderc = { git = "https://github.com/pythonesque/shaderc-rs", rev = "f2605a02062834019bedff911aee2fd2998c49f9" }
@ -71,15 +71,16 @@ cmake = "=0.1.45"
conrod_core = {git = "https://gitlab.com/veloren/conrod.git", branch="copypasta_0.7"}
conrod_winit = {git = "https://gitlab.com/veloren/conrod.git", branch="copypasta_0.7"}
euc = "0.5.0"
iced = {package = "iced_native", git = "https://github.com/Imberflur/iced", tag = "veloren-winit-0.28"}
iced_winit = {git = "https://github.com/Imberflur/iced", tag = "veloren-winit-0.28"}
iced = {package = "iced_native", git = "https://github.com/JCapucho/iced", branch = "winit-updates"}
iced_winit = {git = "https://github.com/JCapucho/iced", branch = "winit-updates"}
window_clipboard = "0.2"
glyph_brush = "0.7.0"
# https://gitlab.com/Frinksy/keyboard-keynames/-/merge_requests/8
keyboard-keynames = { git = "https://gitlab.com/Imbris/keyboard-keynames.git", tag = "veloren-winit-0.28" }
# EGUI
egui = {version = "0.12", optional = true }
egui_wgpu_backend = {git = "https://github.com/hasenbanck/egui_wgpu_backend.git", rev = "63a002c6a9b6c016e45806dd065864431caab621", optional = true }
egui_winit_platform = { git = "https://github.com/Imberflur/egui_winit_platform.git", tag = "veloren-winit-0.28", optional = true }
egui = {version = "0.23", optional = true }
egui_wgpu_backend = { git = "https://github.com/hasenbanck/egui_wgpu_backend.git", rev = "34691d4e9149deb9cd0bb8cbb5a56bffebf47588", optional = true }
egui_winit_platform = { version = "0.20", optional = true }
# ECS
specs = { workspace = true, features = ["serde", "storage-event-control"] }

View File

@ -11,8 +11,9 @@ be-dyn-lib = []
[dependencies]
client = {package = "veloren-client", path = "../../client"}
common = {package = "veloren-common", path = "../../common"}
egui = "0.12"
egui_winit_platform = { git = "https://github.com/Imberflur/egui_winit_platform.git", tag = "veloren-winit-0.28" }
egui = "0.23"
egui_plot = "0.23"
egui_winit_platform = "0.20"
lazy_static = { workspace = true }
common-dynlib = {package = "veloren-common-dynlib", path = "../../common/dynlib", optional = true}

View File

@ -1,6 +1,6 @@
use crate::{AdminCommandState, EguiAction, EguiActions};
use common::cmd::ServerChatCommand;
use egui::{CollapsingHeader, CtxRef, Resize, Slider, Ui, Vec2, Window};
use egui::{style::Margin, CollapsingHeader, Context, Resize, Slider, Ui, Vec2, Window};
use lazy_static::lazy_static;
lazy_static! {
@ -25,7 +25,7 @@ lazy_static! {
}
pub fn draw_admin_commands_window(
ctx: &CtxRef,
ctx: &Context,
state: &mut AdminCommandState,
open: &mut bool,
egui_actions: &mut EguiActions,
@ -69,7 +69,7 @@ fn draw_kits(ui: &mut Ui, state: &mut AdminCommandState, egui_actions: &mut Egui
}
fn draw_give_items(ui: &mut Ui, state: &mut AdminCommandState, egui_actions: &mut EguiActions) {
ui.spacing_mut().window_padding = Vec2::new(10.0, 10.0);
ui.spacing_mut().window_margin = Margin::same(10.0);
Resize::default()
.default_size([400.0, 200.0])
.show(ui, |ui| {
@ -108,7 +108,7 @@ fn draw_give_items(ui: &mut Ui, state: &mut AdminCommandState, egui_actions: &mu
});
}
fn draw_spawn_entities(ui: &mut Ui, state: &mut AdminCommandState, egui_actions: &mut EguiActions) {
ui.spacing_mut().window_padding = Vec2::new(10.0, 10.0);
ui.spacing_mut().window_margin = Margin::symmetric(10.0, 10.0);
Resize::default()
.default_size([400.0, 200.0])
.show(ui, |ui| {

View File

@ -1,8 +1,8 @@
use crate::{EguiAction, EguiActions};
use egui::{CtxRef, Vec2, Window};
use egui::{Context, Vec2, Window};
pub fn draw_experimental_shaders_window(
ctx: &CtxRef,
ctx: &Context,
open: &mut bool,
egui_actions: &mut EguiActions,
experimental_shaders: &[(String, bool)],

View File

@ -19,11 +19,8 @@ use common::{
resources::Time,
};
use core::mem;
use egui::{
plot::{Plot, Value},
widgets::plot::Curve,
CollapsingHeader, Color32, Grid, Pos2, ScrollArea, Slider, Ui, Window,
};
use egui::{CollapsingHeader, Color32, Grid, Pos2, ScrollArea, Slider, Ui, Window};
use egui_plot::{Line, Plot, PlotPoints};
use crate::{
admin::draw_admin_commands_window, character_states::draw_char_state_group,
@ -281,13 +278,13 @@ pub fn maintain_egui_inner(
Window::new("🔧 Settings")
.open(&mut windows.egui_settings)
.scroll(true)
.vscroll(true)
.show(ctx, |ui| {
ctx.settings_ui(ui);
});
Window::new("🔍 Inspection")
.open(&mut windows.egui_inspection)
.scroll(true)
.vscroll(true)
.show(ctx, |ui| {
ctx.inspection_ui(ui);
});
@ -304,14 +301,15 @@ pub fn maintain_egui_inner(
.default_width(200.0)
.default_height(200.0)
.show(ctx, |ui| {
let plot = Plot::new("Frame Time").curve(Curve::from_values_iter(
egui_state
.frame_times
.iter()
.enumerate()
.map(|(i, x)| Value::new(i as f64, *x)),
));
ui.add(plot);
Plot::new("Frame Time").show(ui, |plot_ui| {
plot_ui.line(Line::new(PlotPoints::from_iter(
egui_state
.frame_times
.iter()
.enumerate()
.map(|(i, x)| [i as f64, *x as f64]),
)))
});
});
if windows.ecs_entities {
@ -340,8 +338,8 @@ pub fn maintain_egui_inner(
.text("Cylinder height"),
);
let scroll_area = ScrollArea::from_max_height(800.0);
let (_current_scroll, _max_scroll) = scroll_area.show(ui, |ui| {
let scroll_area = ScrollArea::vertical().max_height(800.0);
scroll_area.show(ui, |ui| {
Grid::new("entities_grid")
.spacing([40.0, 4.0])
.max_col_width(300.0)

View File

@ -1,4 +1,4 @@
use egui::{Label, ScrollArea, Ui, Vec2};
use egui::{ScrollArea, Ui, Vec2, WidgetText};
pub(crate) fn filterable_list(
ui: &mut Ui,
@ -6,7 +6,7 @@ pub(crate) fn filterable_list(
search_text: &str,
selected_index: &mut usize,
) {
let scroll_area = ScrollArea::auto_sized();
let scroll_area = ScrollArea::vertical();
scroll_area.show(ui, |ui| {
ui.spacing_mut().item_spacing = Vec2::new(0.0, 2.0);
let search_text = search_text.to_lowercase();
@ -27,7 +27,11 @@ pub(crate) fn filterable_list(
});
}
pub(crate) fn two_col_row(ui: &mut Ui, label: impl Into<Label>, content: impl Into<Label>) {
pub(crate) fn two_col_row(
ui: &mut Ui,
label: impl Into<WidgetText>,
content: impl Into<WidgetText>,
) {
ui.label(label);
ui.label(content);
ui.end_row();

View File

@ -1549,7 +1549,7 @@ impl<'a> Widget for Video<'a> {
.iter()
.filter(
|mode| match self.global_state.settings.graphics.fullscreen.refresh_rate_millihertz {
Some(rate) => mode.refresh_rate_millihertz() == rate,
Some(refresh_rate) => mode.refresh_rate_millihertz() == refresh_rate,
None => true,
},
)
@ -1610,9 +1610,8 @@ impl<'a> Widget for Video<'a> {
None => true,
},
)
// TODO: why do we sort by this and then map to it?
.sorted_by_key(|mode| mode.refresh_rate_millihertz())
.map(|mode| mode.refresh_rate_millihertz())
.sorted()
.rev()
.dedup()
.collect();

View File

@ -324,7 +324,8 @@ impl PlayState for CharSelectionState {
// Bloom (does nothing if bloom is disabled)
drawer.run_bloom_passes();
// PostProcess and UI
let mut third_pass = drawer.third_pass();
let mut third_pass_prepared = drawer.prepare_third_pass();
let mut third_pass = third_pass_prepared.drawer();
third_pass.draw_postprocess();
// Draw the UI to the screen.
if let Some(mut ui_drawer) = third_pass.draw_ui() {

View File

@ -11,7 +11,7 @@ impl Scene {
pub fn new(renderer: &mut Renderer) -> Self {
let global_data = GlobalModel {
globals: renderer.create_consts(&[Globals::default()]),
lights: renderer.create_consts(&[Light::default(); 32]),
lights: renderer.create_consts(&[Light::default(); 20]),
shadows: renderer.create_consts(&[Shadow::default(); 32]),
shadow_mats: renderer.create_shadow_bound_locals(&[ShadowLocals::default()]),
rain_occlusion_mats: renderer

View File

@ -468,7 +468,8 @@ impl PlayState for MainMenuState {
fn render(&self, drawer: &mut Drawer<'_>, _: &Settings) {
// Draw the UI to the screen.
let mut third_pass = drawer.third_pass();
let mut third_pass_prepared = drawer.prepare_third_pass();
let mut third_pass = third_pass_prepared.drawer();
if let Some(mut ui_drawer) = third_pass.draw_ui() {
self.main_menu_ui.render(&mut ui_drawer);
};

View File

@ -10,7 +10,7 @@ pub struct Buffer<T: Copy + Pod> {
}
impl<T: Copy + Pod> Buffer<T> {
pub fn new(device: &wgpu::Device, usage: wgpu::BufferUsage, data: &[T]) -> Self {
pub fn new(device: &wgpu::Device, usage: wgpu::BufferUsages, data: &[T]) -> Self {
let contents = bytemuck::cast_slice(data);
Self {
@ -31,13 +31,13 @@ impl<T: Copy + Pod> Buffer<T> {
pub struct DynamicBuffer<T: Copy + Pod>(Buffer<T>);
impl<T: Copy + Pod> DynamicBuffer<T> {
pub fn new(device: &wgpu::Device, len: usize, usage: wgpu::BufferUsage) -> Self {
pub fn new(device: &wgpu::Device, len: usize, usage: wgpu::BufferUsages) -> Self {
let buffer = Buffer {
buf: device.create_buffer(&wgpu::BufferDescriptor {
label: None,
mapped_at_creation: false,
size: len as u64 * std::mem::size_of::<T>() as u64,
usage: usage | wgpu::BufferUsage::COPY_DST,
usage: usage | wgpu::BufferUsages::COPY_DST,
}),
len,
phantom_data: std::marker::PhantomData,

View File

@ -13,7 +13,7 @@ impl<T: Copy + Pod> Consts<T> {
pub fn new(device: &wgpu::Device, len: usize) -> Self {
Self {
// TODO: examine if all our consts need to be updatable
buf: DynamicBuffer::new(device, len, wgpu::BufferUsage::UNIFORM),
buf: DynamicBuffer::new(device, len, wgpu::BufferUsages::UNIFORM),
}
}

View File

@ -3,11 +3,12 @@
pub enum RenderError {
RequestDeviceError(wgpu::RequestDeviceError),
MappingError(wgpu::BufferAsyncError),
SwapChainError(wgpu::SwapChainError),
SurfaceError(wgpu::SurfaceError),
CustomError(String),
CouldNotFindAdapter,
ErrorInitializingCompiler,
ShaderError(String, shaderc::Error),
ProfilerCreationError(wgpu_profiler::CreationError),
}
use std::fmt;
@ -18,8 +19,8 @@ impl fmt::Debug for RenderError {
f.debug_tuple("RequestDeviceError").field(err).finish()
},
Self::MappingError(err) => f.debug_tuple("MappingError").field(err).finish(),
Self::SwapChainError(err) => f
.debug_tuple("SwapChainError")
Self::SurfaceError(err) => f
.debug_tuple("SurfaceError")
// Use Display formatting for this error since they have nice descriptions
.field(&format!("{}", err))
.finish(),
@ -28,9 +29,9 @@ impl fmt::Debug for RenderError {
Self::ErrorInitializingCompiler => f.debug_tuple("ErrorInitializingCompiler").finish(),
Self::ShaderError(shader_name, err) => write!(
f,
"\"{}\" shader failed to compile due to the following error: {}",
shader_name, err
"\"{shader_name}\" shader failed to compile due to the following error: {err}",
),
RenderError::ProfilerCreationError(err) => write!(f, "Profiler creation error: {err}"),
}
}
}
@ -43,8 +44,8 @@ impl From<wgpu::BufferAsyncError> for RenderError {
fn from(err: wgpu::BufferAsyncError) -> Self { Self::MappingError(err) }
}
impl From<wgpu::SwapChainError> for RenderError {
fn from(err: wgpu::SwapChainError) -> Self { Self::SwapChainError(err) }
impl From<wgpu::SurfaceError> for RenderError {
fn from(err: wgpu::SurfaceError) -> Self { Self::SurfaceError(err) }
}
impl From<(&str, shaderc::Error)> for RenderError {

View File

@ -31,7 +31,7 @@ impl<T: Copy + Pod> Instances<T> {
Self {
// TODO: examine if we have Instances that are not updated (e.g. sprites) and if there
// would be any gains from separating those out
buf: DynamicBuffer::new(device, len, wgpu::BufferUsage::VERTEX),
buf: DynamicBuffer::new(device, len, wgpu::BufferUsages::VERTEX),
}
}

View File

@ -36,7 +36,7 @@ impl<V: Vertex> Model<V> {
}
Some(Self {
vbuf: Buffer::new(device, wgpu::BufferUsage::VERTEX, mesh.vertices()),
vbuf: Buffer::new(device, wgpu::BufferUsages::VERTEX, mesh.vertices()),
})
}
@ -64,7 +64,7 @@ pub struct DynamicModel<V: Vertex> {
impl<V: Vertex> DynamicModel<V> {
pub fn new(device: &wgpu::Device, size: usize) -> Self {
Self {
vbuf: DynamicBuffer::new(device, size, wgpu::BufferUsage::VERTEX),
vbuf: DynamicBuffer::new(device, size, wgpu::BufferUsages::VERTEX),
}
}

View File

@ -15,7 +15,7 @@ impl BlitLayout {
// Color source
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: true },
view_dimension: wgpu::TextureViewDimension::D2,
@ -25,11 +25,8 @@ impl BlitLayout {
},
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler {
filtering: true,
comparison: false,
},
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
count: None,
},
],
@ -71,7 +68,7 @@ impl BlitPipeline {
device: &wgpu::Device,
vs_module: &wgpu::ShaderModule,
fs_module: &wgpu::ShaderModule,
sc_desc: &wgpu::SwapChainDescriptor,
surface_config: &wgpu::SurfaceConfiguration,
layout: &BlitLayout,
) -> Self {
common_base::span!(_guard, "BlitPipeline::new");
@ -95,7 +92,7 @@ impl BlitPipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: None,
clamp_depth: false,
unclipped_depth: false,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -108,12 +105,13 @@ impl BlitPipeline {
fragment: Some(wgpu::FragmentState {
module: fs_module,
entry_point: "main",
targets: &[wgpu::ColorTargetState {
format: sc_desc.format,
targets: &[Some(wgpu::ColorTargetState {
format: surface_config.format,
blend: None,
write_mask: wgpu::ColorWrite::ALL,
}],
write_mask: wgpu::ColorWrites::ALL,
})],
}),
multiview: None,
});
Self {

View File

@ -74,7 +74,7 @@ impl BloomLayout {
// Color source
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: true },
view_dimension: wgpu::TextureViewDimension::D2,
@ -84,17 +84,14 @@ impl BloomLayout {
},
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler {
filtering: true,
comparison: false,
},
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
count: None,
},
// halfpixel
wgpu::BindGroupLayoutEntry {
binding: 2,
visibility: wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
@ -176,7 +173,7 @@ impl BloomPipelines {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: None,
clamp_depth: false,
unclipped_depth: false,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -189,12 +186,13 @@ impl BloomPipelines {
fragment: Some(wgpu::FragmentState {
module: fs_module,
entry_point: "main",
targets: &[wgpu::ColorTargetState {
targets: &[Some(wgpu::ColorTargetState {
format: target_format,
blend,
write_mask: wgpu::ColorWrite::ALL,
}],
write_mask: wgpu::ColorWrites::ALL,
})],
}),
multiview: None,
})
};

View File

@ -40,7 +40,7 @@ impl CloudsLayout {
// Color source
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: true },
view_dimension: wgpu::TextureViewDimension::D2,
@ -50,17 +50,14 @@ impl CloudsLayout {
},
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler {
filtering: true,
comparison: false,
},
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
count: None,
},
// Depth source
wgpu::BindGroupLayoutEntry {
binding: 2,
visibility: wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: false },
view_dimension: wgpu::TextureViewDimension::D2,
@ -70,17 +67,14 @@ impl CloudsLayout {
},
wgpu::BindGroupLayoutEntry {
binding: 3,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler {
filtering: false,
comparison: false,
},
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::NonFiltering),
count: None,
},
// Locals
wgpu::BindGroupLayoutEntry {
binding: 4,
visibility: wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
@ -91,7 +85,7 @@ impl CloudsLayout {
// Materials source
wgpu::BindGroupLayoutEntry {
binding: 5,
visibility: wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Uint,
view_dimension: wgpu::TextureViewDimension::D2,
@ -161,6 +155,7 @@ impl CloudsPipeline {
global_layout: &GlobalsLayouts,
layout: &CloudsLayout,
aa_mode: AaMode,
format: wgpu::TextureFormat,
) -> Self {
common_base::span!(_guard, "CloudsPipeline::new");
let render_pipeline_layout =
@ -189,7 +184,7 @@ impl CloudsPipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: None,
clamp_depth: false,
unclipped_depth: false,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -202,12 +197,13 @@ impl CloudsPipeline {
fragment: Some(wgpu::FragmentState {
module: fs_module,
entry_point: "main",
targets: &[wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba16Float,
targets: &[Some(wgpu::ColorTargetState {
format,
blend: None,
write_mask: wgpu::ColorWrite::ALL,
}],
write_mask: wgpu::ColorWrites::ALL,
})],
}),
multiview: None,
});
Self {

View File

@ -17,7 +17,7 @@ impl Vertex {
wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x4, 2 => Float32x3];
wgpu::VertexBufferLayout {
array_stride: Self::STRIDE,
step_mode: wgpu::InputStepMode::Vertex,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &ATTRIBUTES,
}
}
@ -74,6 +74,7 @@ impl DebugPipeline {
global_layouts: &GlobalsLayouts,
layout: &DebugLayout,
aa_mode: AaMode,
format: wgpu::TextureFormat,
) -> Self {
common_base::span!(_guard, "DebugPipeline::new");
let render_pipeline_layout =
@ -102,7 +103,7 @@ impl DebugPipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: Some(wgpu::Face::Back),
clamp_depth: false,
unclipped_depth: true,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -114,7 +115,7 @@ impl DebugPipeline {
front: wgpu::StencilFaceState::IGNORE,
back: wgpu::StencilFaceState::IGNORE,
read_mask: !0,
write_mask: !0,
write_mask: 0,
},
bias: wgpu::DepthBiasState {
constant: 0,
@ -131,18 +132,19 @@ impl DebugPipeline {
module: fs_module,
entry_point: "main",
targets: &[
wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba16Float,
Some(wgpu::ColorTargetState {
format,
blend: Some(wgpu::BlendState::ALPHA_BLENDING),
write_mask: wgpu::ColorWrite::ALL,
},
wgpu::ColorTargetState {
write_mask: wgpu::ColorWrites::ALL,
}),
Some(wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba8Uint,
blend: None,
write_mask: wgpu::ColorWrite::empty(),
},
write_mask: wgpu::ColorWrites::empty(),
}),
],
}),
multiview: None,
});
Self {
@ -162,7 +164,7 @@ impl DebugLayout {
label: None,
entries: &[wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,

View File

@ -113,7 +113,7 @@ impl FigureLayout {
// locals
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
@ -124,7 +124,7 @@ impl FigureLayout {
// bone data
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
@ -177,6 +177,7 @@ impl FigurePipeline {
global_layout: &GlobalsLayouts,
layout: &FigureLayout,
aa_mode: AaMode,
format: wgpu::TextureFormat,
) -> Self {
common_base::span!(_guard, "FigurePipeline::new");
let render_pipeline_layout =
@ -206,7 +207,7 @@ impl FigurePipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: Some(wgpu::Face::Back),
clamp_depth: false,
unclipped_depth: false,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -218,7 +219,7 @@ impl FigurePipeline {
front: wgpu::StencilFaceState::IGNORE,
back: wgpu::StencilFaceState::IGNORE,
read_mask: !0,
write_mask: !0,
write_mask: 0,
},
bias: wgpu::DepthBiasState {
constant: 0,
@ -235,18 +236,19 @@ impl FigurePipeline {
module: fs_module,
entry_point: "main",
targets: &[
wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba16Float,
Some(wgpu::ColorTargetState {
format,
blend: None,
write_mask: wgpu::ColorWrite::ALL,
},
wgpu::ColorTargetState {
write_mask: wgpu::ColorWrites::ALL,
}),
Some(wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba8Uint,
blend: None,
write_mask: wgpu::ColorWrite::ALL,
},
write_mask: wgpu::ColorWrites::ALL,
}),
],
}),
multiview: None,
});
Self {
@ -284,7 +286,7 @@ impl AtlasData for FigureSpriteAtlasData {
// col lights
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: true },
view_dimension: wgpu::TextureViewDimension::D2,
@ -294,11 +296,8 @@ impl AtlasData for FigureSpriteAtlasData {
},
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler {
filtering: true,
comparison: false,
},
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
count: None,
},
]

View File

@ -43,7 +43,7 @@ impl Vertex {
];
wgpu::VertexBufferLayout {
array_stride: Self::STRIDE,
step_mode: wgpu::InputStepMode::Vertex,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &ATTRIBUTES,
}
}
@ -66,6 +66,7 @@ impl FluidPipeline {
global_layout: &GlobalsLayouts,
terrain_layout: &TerrainLayout,
aa_mode: AaMode,
format: wgpu::TextureFormat,
) -> Self {
common_base::span!(_guard, "FluidPipeline::new");
let render_pipeline_layout =
@ -94,7 +95,7 @@ impl FluidPipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: None,
clamp_depth: false,
unclipped_depth: false,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -106,7 +107,7 @@ impl FluidPipeline {
front: wgpu::StencilFaceState::IGNORE,
back: wgpu::StencilFaceState::IGNORE,
read_mask: !0,
write_mask: !0,
write_mask: 0,
},
bias: wgpu::DepthBiasState {
constant: 0,
@ -123,8 +124,8 @@ impl FluidPipeline {
module: fs_module,
entry_point: "main",
targets: &[
wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba16Float,
Some(wgpu::ColorTargetState {
format,
blend: Some(wgpu::BlendState {
color: wgpu::BlendComponent {
src_factor: wgpu::BlendFactor::SrcAlpha,
@ -137,15 +138,16 @@ impl FluidPipeline {
operation: wgpu::BlendOperation::Min,
},
}),
write_mask: wgpu::ColorWrite::ALL,
},
wgpu::ColorTargetState {
write_mask: wgpu::ColorWrites::ALL,
}),
Some(wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba8Uint,
blend: None,
write_mask: wgpu::ColorWrite::ALL,
},
write_mask: wgpu::ColorWrites::ALL,
}),
],
}),
multiview: None,
});
Self {

View File

@ -25,7 +25,7 @@ impl Vertex {
wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x3, 2 => Float32x3];
wgpu::VertexBufferLayout {
array_stride: Self::STRIDE,
step_mode: wgpu::InputStepMode::Vertex,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &ATTRIBUTES,
}
}
@ -61,7 +61,7 @@ impl Instance {
];
wgpu::VertexBufferLayout {
array_stride: mem::size_of::<Self>() as wgpu::BufferAddress,
step_mode: wgpu::InputStepMode::Instance,
step_mode: wgpu::VertexStepMode::Instance,
attributes: &ATTRIBUTES,
}
}
@ -85,6 +85,7 @@ impl LodObjectPipeline {
fs_module: &wgpu::ShaderModule,
global_layout: &GlobalsLayouts,
aa_mode: AaMode,
format: wgpu::TextureFormat,
) -> Self {
common_base::span!(_guard, "LodObjectPipeline::new");
let render_pipeline_layout =
@ -109,7 +110,7 @@ impl LodObjectPipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: Some(wgpu::Face::Back),
clamp_depth: false,
unclipped_depth: false,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -121,7 +122,7 @@ impl LodObjectPipeline {
front: wgpu::StencilFaceState::IGNORE,
back: wgpu::StencilFaceState::IGNORE,
read_mask: !0,
write_mask: !0,
write_mask: 0,
},
bias: wgpu::DepthBiasState {
constant: 0,
@ -138,18 +139,19 @@ impl LodObjectPipeline {
module: fs_module,
entry_point: "main",
targets: &[
wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba16Float,
Some(wgpu::ColorTargetState {
format,
blend: Some(wgpu::BlendState::REPLACE),
write_mask: wgpu::ColorWrite::ALL,
},
wgpu::ColorTargetState {
write_mask: wgpu::ColorWrites::ALL,
}),
Some(wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba8Uint,
blend: None,
write_mask: wgpu::ColorWrite::ALL,
},
write_mask: wgpu::ColorWrites::ALL,
}),
],
}),
multiview: None,
});
Self {

View File

@ -20,7 +20,7 @@ impl Vertex {
const ATTRIBUTES: [wgpu::VertexAttribute; 1] = wgpu::vertex_attr_array![0 => Float32x2];
wgpu::VertexBufferLayout {
array_stride: Self::STRIDE,
step_mode: wgpu::InputStepMode::Vertex,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &ATTRIBUTES,
}
}
@ -81,7 +81,8 @@ impl LodData {
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format,
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
view_formats: &[],
};
let sampler_info = wgpu::SamplerDescriptor {
@ -147,7 +148,8 @@ impl LodData {
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Rgba8Unorm,
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
view_formats: &[],
};
let sampler_info = wgpu::SamplerDescriptor {
@ -201,6 +203,7 @@ impl LodTerrainPipeline {
fs_module: &wgpu::ShaderModule,
global_layout: &GlobalsLayouts,
aa_mode: AaMode,
format: wgpu::TextureFormat,
) -> Self {
let render_pipeline_layout =
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
@ -224,7 +227,7 @@ impl LodTerrainPipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: Some(wgpu::Face::Back),
clamp_depth: false,
unclipped_depth: false,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -236,7 +239,7 @@ impl LodTerrainPipeline {
front: wgpu::StencilFaceState::IGNORE,
back: wgpu::StencilFaceState::IGNORE,
read_mask: !0,
write_mask: !0,
write_mask: 0,
},
bias: wgpu::DepthBiasState {
constant: 0,
@ -253,18 +256,19 @@ impl LodTerrainPipeline {
module: fs_module,
entry_point: "main",
targets: &[
wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba16Float,
Some(wgpu::ColorTargetState {
format,
blend: None,
write_mask: wgpu::ColorWrite::ALL,
},
wgpu::ColorTargetState {
write_mask: wgpu::ColorWrites::ALL,
}),
Some(wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba8Uint,
blend: None,
write_mask: wgpu::ColorWrite::ALL,
},
write_mask: wgpu::ColorWrites::ALL,
}),
],
}),
multiview: None,
});
Self {

View File

@ -383,7 +383,8 @@ pub trait AtlasData {
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: fmt,
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
view_formats: &[],
};
let sampler_info = wgpu::SamplerDescriptor {
@ -420,7 +421,7 @@ impl GlobalsLayouts {
// Global uniform
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
@ -431,7 +432,7 @@ impl GlobalsLayouts {
// Noise tex
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: true },
view_dimension: wgpu::TextureViewDimension::D2,
@ -441,17 +442,14 @@ impl GlobalsLayouts {
},
wgpu::BindGroupLayoutEntry {
binding: 2,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler {
filtering: true,
comparison: false,
},
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
count: None,
},
// Light uniform
wgpu::BindGroupLayoutEntry {
binding: 3,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
@ -462,7 +460,7 @@ impl GlobalsLayouts {
// Shadow uniform
wgpu::BindGroupLayoutEntry {
binding: 4,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
@ -473,7 +471,7 @@ impl GlobalsLayouts {
// Alt texture
wgpu::BindGroupLayoutEntry {
binding: 5,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: true },
view_dimension: wgpu::TextureViewDimension::D2,
@ -483,17 +481,14 @@ impl GlobalsLayouts {
},
wgpu::BindGroupLayoutEntry {
binding: 6,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler {
filtering: true,
comparison: false,
},
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
count: None,
},
// Horizon texture
wgpu::BindGroupLayoutEntry {
binding: 7,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: true },
view_dimension: wgpu::TextureViewDimension::D2,
@ -503,17 +498,14 @@ impl GlobalsLayouts {
},
wgpu::BindGroupLayoutEntry {
binding: 8,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler {
filtering: true,
comparison: false,
},
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
count: None,
},
// light shadows (ie shadows from a light?)
wgpu::BindGroupLayoutEntry {
binding: 9,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
// TODO: is this relevant?
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
@ -525,7 +517,7 @@ impl GlobalsLayouts {
// lod map (t_map)
wgpu::BindGroupLayoutEntry {
binding: 10,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: true },
view_dimension: wgpu::TextureViewDimension::D2,
@ -535,17 +527,14 @@ impl GlobalsLayouts {
},
wgpu::BindGroupLayoutEntry {
binding: 11,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler {
filtering: true,
comparison: false,
},
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
count: None,
},
// clouds t_weather
wgpu::BindGroupLayoutEntry {
binding: 12,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: true },
view_dimension: wgpu::TextureViewDimension::D2,
@ -555,17 +544,14 @@ impl GlobalsLayouts {
},
wgpu::BindGroupLayoutEntry {
binding: 13,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler {
filtering: true,
comparison: false,
},
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
count: None,
},
// rain occlusion
wgpu::BindGroupLayoutEntry {
binding: 14,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
@ -588,7 +574,7 @@ impl GlobalsLayouts {
// point shadow_maps
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Depth,
view_dimension: wgpu::TextureViewDimension::Cube,
@ -598,17 +584,14 @@ impl GlobalsLayouts {
},
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler {
filtering: true,
comparison: true,
},
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Comparison),
count: None,
},
// directed shadow maps
wgpu::BindGroupLayoutEntry {
binding: 2,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Depth,
view_dimension: wgpu::TextureViewDimension::D2,
@ -618,17 +601,14 @@ impl GlobalsLayouts {
},
wgpu::BindGroupLayoutEntry {
binding: 3,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler {
filtering: true,
comparison: true,
},
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Comparison),
count: None,
},
// Rain occlusion maps
wgpu::BindGroupLayoutEntry {
binding: 4,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Depth,
view_dimension: wgpu::TextureViewDimension::D2,
@ -638,11 +618,8 @@ impl GlobalsLayouts {
},
wgpu::BindGroupLayoutEntry {
binding: 5,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler {
filtering: true,
comparison: true,
},
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Comparison),
count: None,
},
],

View File

@ -38,7 +38,7 @@ impl Vertex {
wgpu::vertex_attr_array![0 => Float32x3, 1 => Uint32];
wgpu::VertexBufferLayout {
array_stride: Self::STRIDE,
step_mode: wgpu::InputStepMode::Vertex,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &ATTRIBUTES,
}
}
@ -190,7 +190,7 @@ impl Instance {
const ATTRIBUTES: [wgpu::VertexAttribute; 6] = wgpu::vertex_attr_array![2 => Float32, 3 => Float32, 4 => Float32, 5 => Sint32, 6 => Float32x3, 7 => Float32x3];
wgpu::VertexBufferLayout {
array_stride: mem::size_of::<Self>() as wgpu::BufferAddress,
step_mode: wgpu::InputStepMode::Instance,
step_mode: wgpu::VertexStepMode::Instance,
attributes: &ATTRIBUTES,
}
}
@ -211,6 +211,7 @@ impl ParticlePipeline {
fs_module: &wgpu::ShaderModule,
global_layout: &GlobalsLayouts,
aa_mode: AaMode,
format: wgpu::TextureFormat,
) -> Self {
common_base::span!(_guard, "ParticlePipeline::new");
let render_pipeline_layout =
@ -235,7 +236,7 @@ impl ParticlePipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: Some(wgpu::Face::Back),
clamp_depth: false,
unclipped_depth: false,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -247,7 +248,7 @@ impl ParticlePipeline {
front: wgpu::StencilFaceState::IGNORE,
back: wgpu::StencilFaceState::IGNORE,
read_mask: !0,
write_mask: !0,
write_mask: 0,
},
bias: wgpu::DepthBiasState {
constant: 0,
@ -264,9 +265,8 @@ impl ParticlePipeline {
module: fs_module,
entry_point: "main",
targets: &[
wgpu::ColorTargetState {
// TODO: use a constant and/or pass in this format on pipeline construction
format: wgpu::TextureFormat::Rgba16Float,
Some(wgpu::ColorTargetState {
format,
blend: Some(wgpu::BlendState {
color: wgpu::BlendComponent {
src_factor: wgpu::BlendFactor::SrcAlpha,
@ -279,15 +279,16 @@ impl ParticlePipeline {
operation: wgpu::BlendOperation::Add,
},
}),
write_mask: wgpu::ColorWrite::ALL,
},
wgpu::ColorTargetState {
write_mask: wgpu::ColorWrites::ALL,
}),
Some(wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba8Uint,
blend: None,
write_mask: wgpu::ColorWrite::ALL,
},
write_mask: wgpu::ColorWrites::ALL,
}),
],
}),
multiview: None,
});
Self {

View File

@ -37,7 +37,7 @@ impl PostProcessLayout {
// src color
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: true },
view_dimension: wgpu::TextureViewDimension::D2,
@ -47,17 +47,14 @@ impl PostProcessLayout {
},
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler {
filtering: true,
comparison: false,
},
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
count: None,
},
// Depth source
wgpu::BindGroupLayoutEntry {
binding: 2,
visibility: wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: false },
view_dimension: wgpu::TextureViewDimension::D2,
@ -67,17 +64,14 @@ impl PostProcessLayout {
},
wgpu::BindGroupLayoutEntry {
binding: 3,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler {
filtering: false,
comparison: false,
},
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::NonFiltering),
count: None,
},
// Locals
wgpu::BindGroupLayoutEntry {
binding: 4,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
@ -93,7 +87,7 @@ impl PostProcessLayout {
// src bloom
wgpu::BindGroupLayoutEntry {
binding,
visibility: wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: true },
view_dimension: wgpu::TextureViewDimension::D2,
@ -111,7 +105,7 @@ impl PostProcessLayout {
// Material source
bind_entries.push(wgpu::BindGroupLayoutEntry {
binding,
visibility: wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Uint,
view_dimension: wgpu::TextureViewDimension::D2,
@ -204,7 +198,7 @@ impl PostProcessPipeline {
device: &wgpu::Device,
vs_module: &wgpu::ShaderModule,
fs_module: &wgpu::ShaderModule,
sc_desc: &wgpu::SwapChainDescriptor,
surface_config: &wgpu::SurfaceConfiguration,
global_layout: &GlobalsLayouts,
layout: &PostProcessLayout,
) -> Self {
@ -229,7 +223,7 @@ impl PostProcessPipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: None,
clamp_depth: false,
unclipped_depth: false,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -242,12 +236,13 @@ impl PostProcessPipeline {
fragment: Some(wgpu::FragmentState {
module: fs_module,
entry_point: "main",
targets: &[wgpu::ColorTargetState {
format: sc_desc.format,
targets: &[Some(wgpu::ColorTargetState {
format: surface_config.format,
blend: None,
write_mask: wgpu::ColorWrite::ALL,
}],
write_mask: wgpu::ColorWrites::ALL,
})],
}),
multiview: None,
});
Self {

View File

@ -53,7 +53,7 @@ impl RainOcclusionLayout {
label: None,
entries: &[wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
@ -118,7 +118,7 @@ impl RainOcclusionFigurePipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: Some(wgpu::Face::Back),
clamp_depth: true,
unclipped_depth: true,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -129,8 +129,8 @@ impl RainOcclusionFigurePipeline {
stencil: wgpu::StencilState {
front: wgpu::StencilFaceState::IGNORE,
back: wgpu::StencilFaceState::IGNORE,
read_mask: !0,
write_mask: !0,
read_mask: 0,
write_mask: 0,
},
bias: wgpu::DepthBiasState {
constant: 0,
@ -144,6 +144,7 @@ impl RainOcclusionFigurePipeline {
alpha_to_coverage_enabled: false,
},
fragment: None,
multiview: None,
});
Self {
@ -186,7 +187,7 @@ impl RainOcclusionPipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: None,
clamp_depth: true,
unclipped_depth: true,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -197,8 +198,8 @@ impl RainOcclusionPipeline {
stencil: wgpu::StencilState {
front: wgpu::StencilFaceState::IGNORE,
back: wgpu::StencilFaceState::IGNORE,
read_mask: !0,
write_mask: !0,
read_mask: 0,
write_mask: 0,
},
bias: wgpu::DepthBiasState {
constant: 0,
@ -212,6 +213,7 @@ impl RainOcclusionPipeline {
alpha_to_coverage_enabled: false,
},
fragment: None,
multiview: None,
});
Self {

View File

@ -47,7 +47,7 @@ impl Vertex {
wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x3];
wgpu::VertexBufferLayout {
array_stride: Self::STRIDE,
step_mode: wgpu::InputStepMode::Vertex,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &ATTRIBUTES,
}
}
@ -71,7 +71,7 @@ impl RopeLayout {
// locals
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
@ -141,7 +141,7 @@ impl RopePipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: Some(wgpu::Face::Back),
clamp_depth: false,
unclipped_depth: false,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -170,7 +170,7 @@ impl RopePipeline {
module: fs_module,
entry_point: "main",
targets: &[
wgpu::ColorTargetState {
Some(wgpu::ColorTargetState {
// TODO: use a constant and/or pass in this format on pipeline construction
format: wgpu::TextureFormat::Rgba16Float,
blend: Some(wgpu::BlendState {
@ -185,15 +185,16 @@ impl RopePipeline {
operation: wgpu::BlendOperation::Add,
},
}),
write_mask: wgpu::ColorWrite::ALL,
},
wgpu::ColorTargetState {
write_mask: wgpu::ColorWrites::ALL,
}),
Some(wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba8Uint,
blend: None,
write_mask: wgpu::ColorWrite::ALL,
},
write_mask: wgpu::ColorWrites::ALL,
}),
],
}),
multiview: None,
});
Self {

View File

@ -38,7 +38,7 @@ impl ShadowLayout {
label: None,
entries: &[wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
@ -115,7 +115,7 @@ impl ShadowFigurePipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: Some(wgpu::Face::Front),
clamp_depth: true,
unclipped_depth: true,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -127,7 +127,7 @@ impl ShadowFigurePipeline {
front: wgpu::StencilFaceState::IGNORE,
back: wgpu::StencilFaceState::IGNORE,
read_mask: !0,
write_mask: !0,
write_mask: 0,
},
bias: wgpu::DepthBiasState {
constant: 0,
@ -141,6 +141,7 @@ impl ShadowFigurePipeline {
alpha_to_coverage_enabled: false,
},
fragment: None,
multiview: None,
});
Self {
@ -183,7 +184,7 @@ impl ShadowPipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: Some(wgpu::Face::Front),
clamp_depth: true,
unclipped_depth: true,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -195,7 +196,7 @@ impl ShadowPipeline {
front: wgpu::StencilFaceState::IGNORE,
back: wgpu::StencilFaceState::IGNORE,
read_mask: !0,
write_mask: !0,
write_mask: 0,
},
bias: wgpu::DepthBiasState {
constant: 0,
@ -209,6 +210,7 @@ impl ShadowPipeline {
alpha_to_coverage_enabled: false,
},
fragment: None,
multiview: None,
});
Self {
@ -232,7 +234,7 @@ impl PointShadowPipeline {
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("Point shadow pipeline layout"),
push_constant_ranges: &[wgpu::PushConstantRange {
stages: wgpu::ShaderStage::all(),
stages: wgpu::ShaderStages::all(),
range: 0..64,
}],
bind_group_layouts: &[&global_layout.globals, &terrain_layout.locals],
@ -253,7 +255,7 @@ impl PointShadowPipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: Some(wgpu::Face::Back),
clamp_depth: false,
unclipped_depth: false,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -265,7 +267,7 @@ impl PointShadowPipeline {
front: wgpu::StencilFaceState::IGNORE,
back: wgpu::StencilFaceState::IGNORE,
read_mask: !0,
write_mask: !0,
write_mask: 0,
},
bias: wgpu::DepthBiasState {
constant: 0,
@ -279,6 +281,7 @@ impl PointShadowPipeline {
alpha_to_coverage_enabled: false,
},
fragment: None,
multiview: None,
});
Self {
@ -321,7 +324,7 @@ impl ShadowDebugPipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: Some(wgpu::Face::Front),
clamp_depth: true,
unclipped_depth: true,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -347,6 +350,7 @@ impl ShadowDebugPipeline {
alpha_to_coverage_enabled: false,
},
fragment: None,
multiview: None,
});
Self {

View File

@ -12,7 +12,7 @@ impl Vertex {
fn desc<'a>() -> wgpu::VertexBufferLayout<'a> {
wgpu::VertexBufferLayout {
array_stride: Self::STRIDE,
step_mode: wgpu::InputStepMode::Vertex,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &[wgpu::VertexAttribute {
offset: 0,
shader_location: 0,
@ -39,6 +39,7 @@ impl SkyboxPipeline {
fs_module: &wgpu::ShaderModule,
layouts: &GlobalsLayouts,
aa_mode: AaMode,
format: wgpu::TextureFormat,
) -> Self {
common_base::span!(_guard, "SkyboxPipeline::new");
let render_pipeline_layout =
@ -63,7 +64,7 @@ impl SkyboxPipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: Some(wgpu::Face::Back),
clamp_depth: false,
unclipped_depth: false,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -75,7 +76,7 @@ impl SkyboxPipeline {
front: wgpu::StencilFaceState::IGNORE,
back: wgpu::StencilFaceState::IGNORE,
read_mask: !0,
write_mask: !0,
write_mask: 0,
},
bias: wgpu::DepthBiasState {
constant: 0,
@ -92,8 +93,8 @@ impl SkyboxPipeline {
module: fs_module,
entry_point: "main",
targets: &[
wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba16Float,
Some(wgpu::ColorTargetState {
format,
blend: Some(wgpu::BlendState {
color: wgpu::BlendComponent::REPLACE,
alpha: wgpu::BlendComponent {
@ -102,15 +103,16 @@ impl SkyboxPipeline {
operation: wgpu::BlendOperation::Add,
},
}),
write_mask: wgpu::ColorWrite::ALL,
},
wgpu::ColorTargetState {
write_mask: wgpu::ColorWrites::ALL,
}),
Some(wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba8Uint,
blend: None,
write_mask: wgpu::ColorWrite::ALL,
},
write_mask: wgpu::ColorWrites::ALL,
}),
],
}),
multiview: None,
});
Self {

View File

@ -86,7 +86,7 @@ pub(in super::super) fn create_verts_buffer(
// TODO: type Buffer by wgpu::BufferUsage
SpriteVerts(Buffer::new(
device,
wgpu::BufferUsage::STORAGE,
wgpu::BufferUsages::STORAGE,
mesh.vertices(),
))
}
@ -154,7 +154,7 @@ impl Instance {
];
wgpu::VertexBufferLayout {
array_stride: mem::size_of::<Self>() as wgpu::BufferAddress,
step_mode: wgpu::InputStepMode::Instance,
step_mode: wgpu::VertexStepMode::Instance,
attributes: &ATTRIBUTES,
}
}
@ -195,7 +195,7 @@ impl SpriteLayout {
// sprite_verts
wgpu::BindGroupLayoutEntry {
binding: 15,
visibility: wgpu::ShaderStage::VERTEX,
visibility: wgpu::ShaderStages::VERTEX,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Storage { read_only: true },
has_dynamic_offset: false,
@ -266,6 +266,7 @@ impl SpritePipeline {
layout: &SpriteLayout,
terrain_layout: &TerrainLayout,
aa_mode: AaMode,
format: wgpu::TextureFormat,
) -> Self {
common_base::span!(_guard, "SpritePipeline::new");
let render_pipeline_layout =
@ -296,7 +297,7 @@ impl SpritePipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: Some(wgpu::Face::Back),
clamp_depth: false,
unclipped_depth: false,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -308,7 +309,7 @@ impl SpritePipeline {
front: wgpu::StencilFaceState::IGNORE,
back: wgpu::StencilFaceState::IGNORE,
read_mask: !0,
write_mask: !0,
write_mask: 0,
},
bias: wgpu::DepthBiasState {
constant: 0,
@ -325,8 +326,8 @@ impl SpritePipeline {
module: fs_module,
entry_point: "main",
targets: &[
wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba16Float,
Some(wgpu::ColorTargetState {
format,
// TODO: can we remove sprite transparency?
blend: Some(wgpu::BlendState {
color: wgpu::BlendComponent {
@ -340,15 +341,16 @@ impl SpritePipeline {
operation: wgpu::BlendOperation::Add,
},
}),
write_mask: wgpu::ColorWrite::ALL,
},
wgpu::ColorTargetState {
write_mask: wgpu::ColorWrites::ALL,
}),
Some(wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba8Uint,
blend: None,
write_mask: wgpu::ColorWrite::ALL,
},
write_mask: wgpu::ColorWrites::ALL,
}),
],
}),
multiview: None,
});
Self {

View File

@ -123,7 +123,7 @@ impl Vertex {
wgpu::vertex_attr_array![0 => Uint32,1 => Uint32];
wgpu::VertexBufferLayout {
array_stride: Self::STRIDE,
step_mode: wgpu::InputStepMode::Vertex,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &ATTRIBUTES,
}
}
@ -189,7 +189,7 @@ impl TerrainLayout {
// locals
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
@ -231,6 +231,7 @@ impl TerrainPipeline {
global_layout: &GlobalsLayouts,
layout: &TerrainLayout,
aa_mode: AaMode,
format: wgpu::TextureFormat,
) -> Self {
common_base::span!(_guard, "TerrainPipeline::new");
let render_pipeline_layout =
@ -260,7 +261,7 @@ impl TerrainPipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: Some(wgpu::Face::Back),
clamp_depth: false,
unclipped_depth: false,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -272,7 +273,7 @@ impl TerrainPipeline {
front: wgpu::StencilFaceState::IGNORE,
back: wgpu::StencilFaceState::IGNORE,
read_mask: !0,
write_mask: !0,
write_mask: 0,
},
bias: wgpu::DepthBiasState {
constant: 0,
@ -289,18 +290,19 @@ impl TerrainPipeline {
module: fs_module,
entry_point: "main",
targets: &[
wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba16Float,
Some(wgpu::ColorTargetState {
format,
blend: None,
write_mask: wgpu::ColorWrite::ALL,
},
wgpu::ColorTargetState {
write_mask: wgpu::ColorWrites::ALL,
}),
Some(wgpu::ColorTargetState {
format: wgpu::TextureFormat::Rgba8Uint,
blend: None,
write_mask: wgpu::ColorWrite::ALL,
},
write_mask: wgpu::ColorWrites::ALL,
}),
],
}),
multiview: None,
});
Self {
@ -343,7 +345,7 @@ impl AtlasData for TerrainAtlasData {
// col lights
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: true },
view_dimension: wgpu::TextureViewDimension::D2,
@ -353,17 +355,14 @@ impl AtlasData for TerrainAtlasData {
},
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler {
filtering: true,
comparison: false,
},
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
count: None,
},
// kind
wgpu::BindGroupLayoutEntry {
binding: 2,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Uint,
view_dimension: wgpu::TextureViewDimension::D2,
@ -373,11 +372,8 @@ impl AtlasData for TerrainAtlasData {
},
wgpu::BindGroupLayoutEntry {
binding: 3,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler {
filtering: false,
comparison: false,
},
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::NonFiltering),
count: None,
},
]

View File

@ -16,7 +16,7 @@ impl Vertex {
const ATTRIBUTES: [wgpu::VertexAttribute; 1] = wgpu::vertex_attr_array![0 => Float32x3];
wgpu::VertexBufferLayout {
array_stride: Self::STRIDE,
step_mode: wgpu::InputStepMode::Vertex,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &ATTRIBUTES,
}
}
@ -64,6 +64,7 @@ impl TrailPipeline {
fs_module: &wgpu::ShaderModule,
global_layout: &GlobalsLayouts,
aa_mode: AaMode,
format: wgpu::TextureFormat,
) -> Self {
common_base::span!(_guard, "TrailPipeline::new");
let render_pipeline_layout =
@ -88,7 +89,7 @@ impl TrailPipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: None,
clamp_depth: false,
unclipped_depth: false,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -116,9 +117,8 @@ impl TrailPipeline {
fragment: Some(wgpu::FragmentState {
module: fs_module,
entry_point: "main",
targets: &[wgpu::ColorTargetState {
// TODO: use a constant and/or pass in this format on pipeline construction
format: wgpu::TextureFormat::Rgba16Float,
targets: &[Some(wgpu::ColorTargetState {
format,
blend: Some(wgpu::BlendState {
color: wgpu::BlendComponent {
src_factor: wgpu::BlendFactor::SrcAlpha,
@ -131,9 +131,10 @@ impl TrailPipeline {
operation: wgpu::BlendOperation::Add,
},
}),
write_mask: wgpu::ColorWrite::ALL,
}],
write_mask: wgpu::ColorWrites::ALL,
})],
}),
multiview: None,
});
Self {

View File

@ -1,6 +1,5 @@
use super::super::{Bound, Consts, GlobalsLayouts, Quad, Texture, Tri, Vertex as VertexTrait};
use bytemuck::{Pod, Zeroable};
use core::num::NonZeroU32;
use std::mem;
use vek::*;
@ -34,7 +33,7 @@ impl Vertex {
];
wgpu::VertexBufferLayout {
array_stride: Self::STRIDE,
step_mode: wgpu::InputStepMode::Vertex,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &ATTRIBUTES,
}
}
@ -156,7 +155,7 @@ impl UiLayout {
// locals
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
@ -172,7 +171,7 @@ impl UiLayout {
// texture
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: true },
view_dimension: wgpu::TextureViewDimension::D2,
@ -182,17 +181,14 @@ impl UiLayout {
},
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::Sampler {
filtering: true,
comparison: false,
},
visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
count: None,
},
// tex_locals
wgpu::BindGroupLayoutEntry {
binding: 2,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
@ -259,7 +255,7 @@ impl UiPipeline {
device: &wgpu::Device,
vs_module: &wgpu::ShaderModule,
fs_module: &wgpu::ShaderModule,
sc_desc: &wgpu::SwapChainDescriptor,
surface_config: &wgpu::SurfaceConfiguration,
global_layout: &GlobalsLayouts,
layout: &UiLayout,
) -> Self {
@ -283,7 +279,7 @@ impl UiPipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: Some(wgpu::Face::Back),
clamp_depth: false,
unclipped_depth: false,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -296,8 +292,8 @@ impl UiPipeline {
fragment: Some(wgpu::FragmentState {
module: fs_module,
entry_point: "main",
targets: &[wgpu::ColorTargetState {
format: sc_desc.format,
targets: &[Some(wgpu::ColorTargetState {
format: surface_config.format,
blend: Some(wgpu::BlendState {
color: wgpu::BlendComponent {
src_factor: wgpu::BlendFactor::SrcAlpha,
@ -310,9 +306,10 @@ impl UiPipeline {
operation: wgpu::BlendOperation::Add,
},
}),
write_mask: wgpu::ColorWrite::ALL,
}],
write_mask: wgpu::ColorWrites::ALL,
})],
}),
multiview: None,
});
Self {
@ -463,7 +460,7 @@ impl PremultiplyAlphaLayout {
// source_texture
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: false },
view_dimension: wgpu::TextureViewDimension::D2,
@ -492,7 +489,7 @@ impl PremultiplyAlphaPipeline {
label: Some("Premultiply alpha pipeline layout"),
bind_group_layouts: &[&layout.source_texture],
push_constant_ranges: &[wgpu::PushConstantRange {
stages: wgpu::ShaderStage::VERTEX,
stages: wgpu::ShaderStages::VERTEX,
range: 0..core::mem::size_of::<PremultiplyAlphaParams>() as u32,
}],
});
@ -510,7 +507,7 @@ impl PremultiplyAlphaPipeline {
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: Some(wgpu::Face::Back),
clamp_depth: false,
unclipped_depth: false,
polygon_mode: wgpu::PolygonMode::Fill,
conservative: false,
},
@ -519,12 +516,13 @@ impl PremultiplyAlphaPipeline {
fragment: Some(wgpu::FragmentState {
module: fs_module,
entry_point: "main",
targets: &[wgpu::ColorTargetState {
targets: &[Some(wgpu::ColorTargetState {
format: UI_IMAGE_FORMAT,
blend: None,
write_mask: wgpu::ColorWrite::ALL,
}],
write_mask: wgpu::ColorWrites::ALL,
})],
}),
multiview: None,
});
Self { pipeline }
@ -584,19 +582,21 @@ impl PremultiplyUpload {
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Rgba8UnormSrgb,
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
view_formats: &[],
});
queue.write_texture(
wgpu::ImageCopyTexture {
texture: &source_tex,
mip_level: 0,
origin: wgpu::Origin3d::ZERO,
aspect: wgpu::TextureAspect::All,
},
&(&**image)[..(image.width() as usize * image.height() as usize * 4)],
wgpu::ImageDataLayout {
offset: 0,
bytes_per_row: NonZeroU32::new(image.width() * 4),
rows_per_image: NonZeroU32::new(image.height()),
bytes_per_row: Some(image.width() * 4),
rows_per_image: Some(image.height()),
},
image_size,
);

View File

@ -34,8 +34,6 @@ use super::{
use common::assets::{self, AssetExt, AssetHandle, ReloadWatcher};
use common_base::span;
use core::convert::TryFrom;
#[cfg(feature = "egui-ui")]
use egui_wgpu_backend::wgpu::TextureFormat;
use std::sync::Arc;
use tracing::{error, info, warn};
use vek::*;
@ -138,8 +136,7 @@ pub struct Renderer {
device: Arc<wgpu::Device>,
queue: wgpu::Queue,
surface: wgpu::Surface,
swap_chain: wgpu::SwapChain,
sc_desc: wgpu::SwapChainDescriptor,
surface_config: wgpu::SurfaceConfiguration,
sampler: wgpu::Sampler,
depth_sampler: wgpu::Sampler,
@ -184,6 +181,9 @@ pub struct Renderer {
// To remember the backend info after initialization for debug purposes
graphics_backend: String,
/// The texture format used for the intermediate rendering passes
intermediate_format: wgpu::TextureFormat,
}
impl Renderer {
@ -204,34 +204,39 @@ impl Renderer {
// TODO: fix panic on wayland with opengl?
// TODO: fix backend defaulting to opengl on wayland.
let backend_bit = std::env::var("WGPU_BACKEND")
let backends = std::env::var("WGPU_BACKEND")
.ok()
.and_then(|backend| match backend.to_lowercase().as_str() {
"vulkan" => Some(wgpu::BackendBit::VULKAN),
"metal" => Some(wgpu::BackendBit::METAL),
"dx12" => Some(wgpu::BackendBit::DX12),
"primary" => Some(wgpu::BackendBit::PRIMARY),
"opengl" | "gl" => Some(wgpu::BackendBit::GL),
"dx11" => Some(wgpu::BackendBit::DX11),
"secondary" => Some(wgpu::BackendBit::SECONDARY),
"all" => Some(wgpu::BackendBit::all()),
"vulkan" => Some(wgpu::Backends::VULKAN),
"metal" => Some(wgpu::Backends::METAL),
"dx12" => Some(wgpu::Backends::DX12),
"primary" => Some(wgpu::Backends::PRIMARY),
"opengl" | "gl" => Some(wgpu::Backends::GL),
"dx11" => Some(wgpu::Backends::DX11),
"secondary" => Some(wgpu::Backends::SECONDARY),
"all" => Some(wgpu::Backends::all()),
_ => None,
})
.unwrap_or(
(wgpu::BackendBit::PRIMARY | wgpu::BackendBit::SECONDARY) & !wgpu::BackendBit::GL,
);
.unwrap_or(wgpu::Backends::PRIMARY | wgpu::Backends::SECONDARY);
let instance = wgpu::Instance::new(backend_bit);
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
backends,
dx12_shader_compiler: wgpu::Dx12Compiler::Fxc,
gles_minor_version: wgpu::Gles3MinorVersion::Automatic,
// TODO: Look into what we want here.
flags: wgpu::InstanceFlags::all(),
});
let dims = window.inner_size();
// This is unsafe because the window handle must be valid, if you find a way to
// have an invalid winit::Window then you have bigger issues
#[allow(unsafe_code)]
let surface = unsafe { instance.create_surface(window) };
let surface =
unsafe { instance.create_surface(window) }.expect("Failed to create a surface");
let adapters = instance
.enumerate_adapters(backend_bit)
.enumerate_adapters(backends)
.enumerate()
.collect::<Vec<_>>();
@ -259,6 +264,7 @@ impl Renderer {
runtime.block_on(instance.request_adapter(&wgpu::RequestAdapterOptionsBase {
power_preference: wgpu::PowerPreference::HighPerformance,
compatible_surface: Some(&surface),
force_fallback_adapter: false,
}))
},
}
@ -310,10 +316,10 @@ impl Renderer {
&wgpu::DeviceDescriptor {
// TODO
label: None,
features: wgpu::Features::DEPTH_CLAMPING
features: wgpu::Features::DEPTH_CLIP_CONTROL
| wgpu::Features::ADDRESS_MODE_CLAMP_TO_BORDER
| wgpu::Features::PUSH_CONSTANTS
| (adapter.features() & wgpu_profiler::GpuProfiler::REQUIRED_WGPU_FEATURES),
| (adapter.features() & wgpu_profiler::GpuProfiler::ALL_WGPU_TIMER_FEATURES),
limits,
},
trace_path,
@ -322,17 +328,17 @@ impl Renderer {
// Set error handler for wgpu errors
// This is better for use than their default because it includes the error in
// the panic message
device.on_uncaptured_error(move |error| {
device.on_uncaptured_error(Box::new(move |error| {
error!("{}", &error);
panic!(
"wgpu error (handling all wgpu errors as fatal):\n{:?}\n{:?}",
&error, &info,
);
});
}));
let profiler_features_enabled = device
.features()
.contains(wgpu_profiler::GpuProfiler::REQUIRED_WGPU_FEATURES);
.intersects(wgpu_profiler::GpuProfiler::ALL_WGPU_TIMER_FEATURES);
if !profiler_features_enabled {
info!(
"The features for GPU profiling (timestamp queries) are not available on this \
@ -340,20 +346,52 @@ impl Renderer {
);
}
let format = adapter
.get_swap_chain_preferred_format(&surface)
.expect("No supported swap chain format found");
info!("Using {:?} as the swapchain format", format);
let surface_capabilities = surface.get_capabilities(&adapter);
let format = surface_capabilities.formats[0];
info!("Using {:?} as the surface format", format);
let sc_desc = wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::RENDER_ATTACHMENT,
let surface_config = wgpu::SurfaceConfiguration {
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
format,
width: dims.width,
height: dims.height,
present_mode: other_modes.present_mode.into(),
alpha_mode: wgpu::CompositeAlphaMode::Opaque,
view_formats: Vec::new(),
};
let swap_chain = device.create_swap_chain(&surface, &sc_desc);
let supported_internal_formats = [wgpu::TextureFormat::Rgba16Float, format];
let intermediate_format = supported_internal_formats
.into_iter()
.find(|format| {
use wgpu::TextureUsages as Usages;
use wgpu::TextureFormatFeatureFlags as Flags;
use super::AaMode;
let features = adapter
.get_texture_format_features(*format);
let usage_ok = features
.allowed_usages
.contains(Usages::RENDER_ATTACHMENT | Usages::COPY_SRC | Usages::TEXTURE_BINDING);
let msaa_flags = match pipeline_modes.aa {
AaMode::None | AaMode::Fxaa | AaMode::Hqx | AaMode::FxUpscale | AaMode::Bilinear => Flags::empty(),
AaMode::MsaaX4 => Flags::MULTISAMPLE_X4,
AaMode::MsaaX8 => Flags::MULTISAMPLE_X8,
AaMode::MsaaX16 => Flags::MULTISAMPLE_X8, // TODO?
};
let flags_ok = features.flags.contains(Flags::FILTERABLE | msaa_flags);
usage_ok && flags_ok
})
// This should be unreachable as the surface format should always support the
// needed capabilities
.expect("No supported intermediate format");
info!("Using {:?} as the intermediate format", intermediate_format);
surface.configure(&device, &surface_config);
let shadow_views = ShadowMap::create_shadow_views(
&device,
@ -429,8 +467,9 @@ impl Renderer {
},
shaders.cloned(),
pipeline_modes.clone(),
sc_desc.clone(), // Note: cheap clone
surface_config.clone(), // Note: cheap clone
shadow_views.is_some(),
intermediate_format,
)?;
let state = State::Interface {
@ -445,6 +484,7 @@ impl Renderer {
(dims.width, dims.height),
&pipeline_modes,
&other_modes,
intermediate_format,
);
let create_sampler = |filter| {
@ -501,21 +541,22 @@ impl Renderer {
create_quad_index_buffer_u16(&device, QUAD_INDEX_BUFFER_U16_START_VERT_LEN as usize);
let quad_index_buffer_u32 =
create_quad_index_buffer_u32(&device, QUAD_INDEX_BUFFER_U32_START_VERT_LEN as usize);
let mut profiler = wgpu_profiler::GpuProfiler::new(4, queue.get_timestamp_period());
other_modes.profiler_enabled &= profiler_features_enabled;
profiler.enable_timer = other_modes.profiler_enabled;
profiler.enable_debug_marker = other_modes.profiler_enabled;
let profiler = wgpu_profiler::GpuProfiler::new(wgpu_profiler::GpuProfilerSettings {
enable_timer_scopes: other_modes.profiler_enabled,
enable_debug_groups: other_modes.profiler_enabled,
max_num_pending_frames: 4,
})
.map_err(RenderError::ProfilerCreationError)?;
#[cfg(feature = "egui-ui")]
let egui_renderpass =
egui_wgpu_backend::RenderPass::new(&device, TextureFormat::Bgra8UnormSrgb, 1);
let egui_renderpass = egui_wgpu_backend::RenderPass::new(&*device, format, 1);
Ok(Self {
device,
queue,
surface,
swap_chain,
sc_desc,
surface_config,
state,
recreation_pending: None,
@ -552,6 +593,8 @@ impl Renderer {
is_minimized: false,
graphics_backend,
intermediate_format,
})
}
@ -588,7 +631,7 @@ impl Renderer {
self.other_modes = other_modes;
// Update present mode in swap chain descriptor
self.sc_desc.present_mode = self.other_modes.present_mode.into();
self.surface_config.present_mode = self.other_modes.present_mode.into();
// Only enable profiling if the wgpu features are enabled
self.other_modes.profiler_enabled &= self.profiler_features_enabled;
@ -597,8 +640,17 @@ impl Renderer {
// Clear the times if disabled
core::mem::take(&mut self.profile_times);
}
self.profiler.enable_timer = self.other_modes.profiler_enabled;
self.profiler.enable_debug_marker = self.other_modes.profiler_enabled;
self.profiler
.change_settings(wgpu_profiler::GpuProfilerSettings {
enable_timer_scopes: self.other_modes.profiler_enabled,
enable_debug_groups: self.other_modes.profiler_enabled,
max_num_pending_frames: 4,
})
.map_err(|err| {
RenderError::ProfilerCreationError(
wgpu_profiler::CreationError::InvalidSettings(err),
)
})?;
// Recreate render target
self.on_resize(self.resolution);
@ -657,9 +709,9 @@ impl Renderer {
self.is_minimized = false;
// Resize swap chain
self.resolution = dims;
self.sc_desc.width = dims.x;
self.sc_desc.height = dims.y;
self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc);
self.surface_config.width = dims.x;
self.surface_config.height = dims.y;
self.surface.configure(&self.device, &self.surface_config);
// Resize other render targets
let (views, bloom_sizes) = Self::create_rt_views(
@ -667,6 +719,7 @@ impl Renderer {
(dims.x, dims.y),
&self.pipeline_modes,
&self.other_modes,
self.intermediate_format,
);
self.views = views;
@ -792,7 +845,7 @@ impl Renderer {
self.queue.submit(std::iter::empty());
}
self.device.poll(wgpu::Maintain::Poll)
self.device.poll(wgpu::Maintain::Poll);
}
/// Create render target views
@ -801,6 +854,7 @@ impl Renderer {
size: (u32, u32),
pipeline_modes: &PipelineModes,
other_modes: &OtherModes,
format: wgpu::TextureFormat,
) -> (Views, [Vec2<f32>; bloom::NUM_SIZES]) {
let upscaled = Vec2::<u32>::from(size)
.map(|e| (e as f32 * other_modes.upscale_mode.factor) as u32)
@ -821,7 +875,9 @@ impl Renderer {
sample_count,
dimension: wgpu::TextureDimension::D2,
format,
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::RENDER_ATTACHMENT,
usage: wgpu::TextureUsages::TEXTURE_BINDING
| wgpu::TextureUsages::RENDER_ATTACHMENT,
view_formats: &[],
});
tex.create_view(&wgpu::TextureViewDescriptor {
@ -837,8 +893,8 @@ impl Renderer {
})
};
let tgt_color_view = color_view(width, height, wgpu::TextureFormat::Rgba16Float);
let tgt_color_pp_view = color_view(width, height, wgpu::TextureFormat::Rgba16Float);
let tgt_color_view = color_view(width, height, format);
let tgt_color_pp_view = color_view(width, height, format);
let tgt_mat_view = color_view(width, height, wgpu::TextureFormat::Rgba8Uint);
@ -851,9 +907,10 @@ impl Renderer {
size
});
let bloom_tgt_views = pipeline_modes.bloom.is_on().then(|| {
bloom_sizes.map(|size| color_view(size.x, size.y, wgpu::TextureFormat::Rgba16Float))
});
let bloom_tgt_views = pipeline_modes
.bloom
.is_on()
.then(|| bloom_sizes.map(|size| color_view(size.x, size.y, format)));
let tgt_depth_tex = device.create_texture(&wgpu::TextureDescriptor {
label: None,
@ -866,7 +923,8 @@ impl Renderer {
sample_count,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Depth32Float,
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::RENDER_ATTACHMENT,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::RENDER_ATTACHMENT,
view_formats: &[],
});
let tgt_depth_view = tgt_depth_tex.create_view(&wgpu::TextureViewDescriptor {
label: None,
@ -890,7 +948,8 @@ impl Renderer {
sample_count,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Depth32Float,
usage: wgpu::TextureUsage::RENDER_ATTACHMENT,
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
view_formats: &[],
});
// TODO: Consider no depth buffer for the final draw to the window?
let win_depth_view = win_depth_tex.create_view(&wgpu::TextureViewDescriptor {
@ -990,7 +1049,8 @@ impl Renderer {
// Try to get the latest profiling results
if self.other_modes.profiler_enabled {
// Note: this lags a few frames behind
if let Some(profile_times) = self.profiler.process_finished_frame() {
let timestamp_period = self.queue.get_timestamp_period();
if let Some(profile_times) = self.profiler.process_finished_frame(timestamp_period) {
self.profile_times = profile_times;
}
}
@ -1168,26 +1228,26 @@ impl Renderer {
}
}
let tex = match self.swap_chain.get_current_frame() {
Ok(frame) => frame.output,
let texture = match self.surface.get_current_texture() {
Ok(texture) => texture,
// If lost recreate the swap chain
Err(err @ wgpu::SwapChainError::Lost) => {
Err(err @ wgpu::SurfaceError::Lost) => {
warn!("{}. Recreating swap chain. A frame will be missed", err);
self.on_resize(self.resolution);
return Ok(None);
},
Err(wgpu::SwapChainError::Timeout) => {
Err(wgpu::SurfaceError::Timeout) => {
// This will probably be resolved on the next frame
// NOTE: we don't log this because it happens very frequently with
// PresentMode::Fifo and unlimited FPS on certain machines
return Ok(None);
},
Err(err @ wgpu::SwapChainError::Outdated) => {
Err(err @ wgpu::SurfaceError::Outdated) => {
warn!("{}. Recreating the swapchain", err);
self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc);
self.surface.configure(&self.device, &self.surface_config);
return Ok(None);
},
Err(err @ wgpu::SwapChainError::OutOfMemory) => return Err(err.into()),
Err(err @ wgpu::SurfaceError::OutOfMemory) => return Err(err.into()),
};
let encoder = self
.device
@ -1195,7 +1255,7 @@ impl Renderer {
label: Some("A render encoder"),
});
Ok(Some(drawer::Drawer::new(encoder, self, tex, globals)))
Ok(Some(drawer::Drawer::new(encoder, self, texture, globals)))
}
/// Recreate the pipelines
@ -1220,8 +1280,9 @@ impl Renderer {
// needs to become a part of the pipeline modes
// (note here since the present mode is accessible
// through the swap chain descriptor)
self.sc_desc.clone(), // Note: cheap clone
self.surface_config.clone(), // Note: cheap clone
shadow.map.is_enabled(),
self.intermediate_format,
),
));
},
@ -1340,11 +1401,8 @@ impl Renderer {
/// Return the maximum supported texture size.
pub fn max_texture_size(&self) -> u32 { Self::max_texture_size_raw(&self.device) }
/// Return the maximum supported texture size from the factory.
fn max_texture_size_raw(_device: &wgpu::Device) -> u32 {
// This value is temporary as there are plans to include a way to get this in
// wgpu this is just a sane standard for now
8192
fn max_texture_size_raw(device: &wgpu::Device) -> u32 {
device.limits().max_texture_dimension_2d
}
/// Create a new immutable texture from the provided image.
@ -1361,7 +1419,7 @@ impl Renderer {
let tex = Texture::new_raw(&self.device, texture_info, view_info, sampler_info);
let size = texture_info.size;
let block_size = texture_info.format.describe().block_size;
let block_size = texture_info.format.block_size(None).unwrap();
assert_eq!(
size.width as usize
* size.height as usize
@ -1536,7 +1594,7 @@ fn create_quad_index_buffer_u16(device: &wgpu::Device, vert_length: usize) -> Bu
.map(|(i, b)| (i / 6 * 4 + b) as u16)
.collect::<Vec<_>>();
Buffer::new(device, wgpu::BufferUsage::INDEX, &indices)
Buffer::new(device, wgpu::BufferUsages::INDEX, &indices)
}
fn create_quad_index_buffer_u32(device: &wgpu::Device, vert_length: usize) -> Buffer<u32> {
@ -1550,7 +1608,7 @@ fn create_quad_index_buffer_u32(device: &wgpu::Device, vert_length: usize) -> Bu
.map(|(i, b)| (i / 6 * 4 + b) as u32)
.collect::<Vec<_>>();
Buffer::new(device, wgpu::BufferUsage::INDEX, &indices)
Buffer::new(device, wgpu::BufferUsages::INDEX, &indices)
}
/// Terrain-related buffers segment themselves by depth to allow us to do

View File

@ -16,7 +16,7 @@ use super::{
Renderer, ShadowMap, ShadowMapRenderer,
};
use common_base::prof_span;
use core::{num::NonZeroU32, ops::Range};
use core::ops::Range;
use std::sync::Arc;
use vek::Aabr;
use wgpu_profiler::scope::{ManualOwningScope, OwningScope, Scope};
@ -73,7 +73,7 @@ struct RendererBorrow<'frame> {
queue: &'frame wgpu::Queue,
device: &'frame wgpu::Device,
#[cfg(feature = "egui-ui")]
sc_desc: &'frame wgpu::SwapChainDescriptor,
surface_config: &'frame wgpu::SurfaceConfiguration,
shadow: Option<&'frame super::Shadow>,
pipelines: Pipelines<'frame>,
locals: &'frame super::locals::Locals,
@ -89,7 +89,7 @@ struct RendererBorrow<'frame> {
pub struct Drawer<'frame> {
encoder: Option<ManualOwningScope<'frame, wgpu::CommandEncoder>>,
borrow: RendererBorrow<'frame>,
swap_tex: wgpu::SwapChainTexture,
surface_texture: Option<wgpu::SurfaceTexture>,
globals: &'frame GlobalsBindGroup,
// Texture and other info for taking a screenshot
// Writes to this instead in the third pass if it is present
@ -100,7 +100,7 @@ impl<'frame> Drawer<'frame> {
pub fn new(
encoder: wgpu::CommandEncoder,
renderer: &'frame mut Renderer,
swap_tex: wgpu::SwapChainTexture,
surface_texture: wgpu::SurfaceTexture,
globals: &'frame GlobalsBindGroup,
) -> Self {
let taking_screenshot = renderer.take_screenshot.take().map(|screenshot_fn| {
@ -108,7 +108,7 @@ impl<'frame> Drawer<'frame> {
&renderer.device,
&renderer.layouts.blit,
&renderer.sampler,
&renderer.sc_desc,
&renderer.surface_config,
screenshot_fn,
)
});
@ -125,7 +125,7 @@ impl<'frame> Drawer<'frame> {
queue: &renderer.queue,
device: &renderer.device,
#[cfg(feature = "egui-ui")]
sc_desc: &renderer.sc_desc,
surface_config: &renderer.surface_config,
shadow,
pipelines,
locals: &renderer.locals,
@ -144,7 +144,7 @@ impl<'frame> Drawer<'frame> {
Self {
encoder: Some(encoder),
borrow,
swap_tex,
surface_texture: Some(surface_texture),
globals,
taking_screenshot,
}
@ -174,10 +174,12 @@ impl<'frame> Drawer<'frame> {
view: &rain_occlusion_renderer.depth.view,
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Clear(1.0),
store: true,
store: wgpu::StoreOp::Store,
}),
stencil_ops: None,
}),
timestamp_writes: None,
occlusion_query_set: None,
},
);
@ -211,10 +213,12 @@ impl<'frame> Drawer<'frame> {
view: &shadow_renderer.directed_depth.view,
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Clear(1.0),
store: true,
store: wgpu::StoreOp::Store,
}),
stencil_ops: None,
}),
timestamp_writes: None,
occlusion_query_set: None,
});
render_pass.set_bind_group(0, &self.globals.bind_group, &[]);
@ -242,31 +246,33 @@ impl<'frame> Drawer<'frame> {
encoder.scoped_render_pass("first_pass", device, &wgpu::RenderPassDescriptor {
label: Some("first pass"),
color_attachments: &[
wgpu::RenderPassColorAttachment {
Some(wgpu::RenderPassColorAttachment {
view: &self.borrow.views.tgt_color,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT),
store: true,
store: wgpu::StoreOp::Store,
},
},
wgpu::RenderPassColorAttachment {
}),
Some(wgpu::RenderPassColorAttachment {
view: &self.borrow.views.tgt_mat,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT),
store: true,
store: wgpu::StoreOp::Store,
},
},
}),
],
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
view: &self.borrow.views.tgt_depth,
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Clear(0.0),
store: true,
store: wgpu::StoreOp::Store,
}),
stencil_ops: None,
}),
timestamp_writes: None,
occlusion_query_set: None,
});
render_pass.set_bind_group(0, &self.globals.bind_group, &[]);
@ -290,15 +296,17 @@ impl<'frame> Drawer<'frame> {
let mut render_pass =
encoder.scoped_render_pass("volumetric_pass", device, &wgpu::RenderPassDescriptor {
label: Some("volumetric pass (clouds)"),
color_attachments: &[wgpu::RenderPassColorAttachment {
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: &self.borrow.views.tgt_color_pp,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT),
store: true,
store: wgpu::StoreOp::Store,
},
}],
})],
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
});
render_pass.set_bind_group(0, &self.globals.bind_group, &[]);
@ -321,22 +329,24 @@ impl<'frame> Drawer<'frame> {
let mut render_pass =
encoder.scoped_render_pass("transparent_pass", device, &wgpu::RenderPassDescriptor {
label: Some("transparent pass (trails)"),
color_attachments: &[wgpu::RenderPassColorAttachment {
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: &self.borrow.views.tgt_color_pp,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Load,
store: true,
store: wgpu::StoreOp::Store,
},
}],
})],
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
view: &self.borrow.views.tgt_depth,
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Load,
store: false,
store: wgpu::StoreOp::Discard,
}),
stencil_ops: None,
}),
timestamp_writes: None,
occlusion_query_set: None,
});
render_pass.set_bind_group(0, &self.globals.bind_group, &[]);
@ -377,12 +387,17 @@ impl<'frame> Drawer<'frame> {
let mut render_pass =
encoder.scoped_render_pass(&label, device, &wgpu::RenderPassDescriptor {
label: Some(&pass_label),
color_attachments: &[wgpu::RenderPassColorAttachment {
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
resolve_target: None,
view,
ops: wgpu::Operations { store: true, load },
}],
ops: wgpu::Operations {
store: wgpu::StoreOp::Store,
load,
},
})],
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
});
render_pass.set_bind_group(0, bind, &[]);
@ -460,83 +475,69 @@ impl<'frame> Drawer<'frame> {
let mut render_pass =
encoder.scoped_render_pass(&profile_name, device, &wgpu::RenderPassDescriptor {
label: Some(&label),
color_attachments: &[wgpu::RenderPassColorAttachment {
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: &target_texture.view,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Load,
store: true,
store: wgpu::StoreOp::Store,
},
}],
})],
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
});
render_pass.set_pipeline(&premultiply_alpha.pipeline);
for upload in &uploads {
let (source_bind_group, push_constant_data) = upload.draw_data(&target_texture);
let bytes = bytemuck::bytes_of(&push_constant_data);
render_pass.set_bind_group(0, source_bind_group, &[]);
render_pass.set_push_constants(wgpu::ShaderStage::VERTEX, 0, bytes);
render_pass.set_push_constants(wgpu::ShaderStages::VERTEX, 0, bytes);
render_pass.draw(0..6, 0..1);
}
}
}
/// Prepares the third pass drawer to be used.
///
/// Note, this automatically calls the internal `run_ui_premultiply_passes`
/// to complete any pending image uploads for the UI.
pub fn third_pass(&mut self) -> ThirdPassDrawer {
pub fn prepare_third_pass(&mut self) -> ThirdPassDrawerPrepared<'_, 'frame> {
self.run_ui_premultiply_passes();
let encoder = self.encoder.as_mut().unwrap();
let device = self.borrow.device;
let mut render_pass =
encoder.scoped_render_pass("third_pass", device, &wgpu::RenderPassDescriptor {
label: Some("third pass (postprocess + ui)"),
color_attachments: &[wgpu::RenderPassColorAttachment {
// If a screenshot was requested render to that as an intermediate texture
// instead
view: self
.taking_screenshot
.as_ref()
.map_or(&self.swap_tex.view, |s| s.texture_view()),
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT),
store: true,
},
}],
depth_stencil_attachment: None,
});
// Create a view to the surface texture.
let view = self.surface_texture.as_ref().unwrap().texture.create_view(
&wgpu::TextureViewDescriptor {
label: Some("Surface texture view"),
..Default::default()
},
);
render_pass.set_bind_group(0, &self.globals.bind_group, &[]);
ThirdPassDrawer {
render_pass,
borrow: &self.borrow,
}
ThirdPassDrawerPrepared { view, drawer: self }
}
#[cfg(feature = "egui-ui")]
pub fn draw_egui(&mut self, platform: &mut Platform, scale_factor: f32) {
span!(guard, "Draw egui");
let (_output, paint_commands) = platform.end_frame();
let output = platform.end_frame(None);
let paint_jobs = platform.context().tessellate(paint_commands);
let paint_jobs = platform.context().tessellate(output.shapes);
let screen_descriptor = ScreenDescriptor {
physical_width: self.borrow.sc_desc.width,
physical_height: self.borrow.sc_desc.height,
physical_width: self.borrow.surface_config.width,
physical_height: self.borrow.surface_config.height,
scale_factor,
};
self.borrow.egui_render_pass.update_texture(
self.borrow.device,
self.borrow.queue,
&platform.context().texture(),
);
self.borrow
.egui_render_pass
.update_user_textures(self.borrow.device, self.borrow.queue);
.add_textures(
self.borrow.device,
self.borrow.queue,
&output.textures_delta,
)
.expect("Failed to update egui textures");
self.borrow.egui_render_pass.update_buffers(
self.borrow.device,
self.borrow.queue,
@ -544,16 +545,31 @@ impl<'frame> Drawer<'frame> {
&screen_descriptor,
);
self.borrow.egui_render_pass.execute(
self.encoder.as_mut().unwrap(),
self.taking_screenshot
.as_ref()
.map_or(&self.swap_tex.view, |s| s.texture_view()),
&paint_jobs,
&screen_descriptor,
None,
let view = self.surface_texture.as_ref().unwrap().texture.create_view(
&wgpu::TextureViewDescriptor {
label: Some("Surface texture view"),
..Default::default()
},
);
self.borrow
.egui_render_pass
.execute(
self.encoder.as_mut().unwrap(),
self.taking_screenshot
.as_ref()
.map_or(&view, |s| s.texture_view()),
&paint_jobs,
&screen_descriptor,
None,
)
.expect("Failed to draw egui");
self.borrow
.egui_render_pass
.remove_textures(output.textures_delta)
.expect("Failed to remove unused egui textures");
drop(guard);
}
@ -593,7 +609,7 @@ impl<'frame> Drawer<'frame> {
base_mip_level: 0,
mip_level_count: None,
base_array_layer: face,
array_layer_count: NonZeroU32::new(1),
array_layer_count: Some(1),
});
let label = format!("point shadow face-{} pass", face);
@ -605,10 +621,12 @@ impl<'frame> Drawer<'frame> {
view: &view,
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Clear(1.0),
store: true,
store: wgpu::StoreOp::Store,
}),
stencil_ops: None,
}),
timestamp_writes: None,
occlusion_query_set: None,
});
render_pass.set_pipeline(&shadow_renderer.point_pipeline.pipeline);
@ -617,7 +635,7 @@ impl<'frame> Drawer<'frame> {
(0../*20*/1).for_each(|point_light| {
render_pass.set_push_constants(
wgpu::ShaderStage::all(),
wgpu::ShaderStages::all(),
0,
&data[(6 * (point_light + 1) * STRIDE + face as usize * STRIDE)
..(6 * (point_light + 1) * STRIDE + (face + 1) as usize * STRIDE)],
@ -656,10 +674,12 @@ impl<'frame> Drawer<'frame> {
view: &shadow_renderer.directed_depth.view,
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Clear(1.0),
store: true,
store: wgpu::StoreOp::Store,
}),
stencil_ops: None,
}),
timestamp_writes: None,
occlusion_query_set: None,
},
);
@ -677,7 +697,7 @@ impl<'frame> Drawer<'frame> {
base_mip_level: 0,
mip_level_count: None,
base_array_layer: face,
array_layer_count: NonZeroU32::new(1),
array_layer_count: Some(1),
});
let label = format!("clear point shadow face-{} pass", face);
@ -688,10 +708,12 @@ impl<'frame> Drawer<'frame> {
view: &view,
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Clear(1.0),
store: true,
store: wgpu::StoreOp::Store,
}),
stencil_ops: None,
}),
timestamp_writes: None,
occlusion_query_set: None,
});
}
}
@ -710,21 +732,30 @@ impl<'frame> Drop for Drawer<'frame> {
.take()
.zip(self.borrow.pipelines.blit())
.map(|(screenshot, blit)| {
let view = self.surface_texture.as_ref().unwrap().texture.create_view(
&wgpu::TextureViewDescriptor {
label: Some("Surface texture view"),
..Default::default()
},
);
// Image needs to be copied from the screenshot texture to the swapchain texture
let mut render_pass = encoder.scoped_render_pass(
"screenshot blit",
self.borrow.device,
&wgpu::RenderPassDescriptor {
label: Some("Blit screenshot pass"),
color_attachments: &[wgpu::RenderPassColorAttachment {
view: &self.swap_tex.view,
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: &view,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT),
store: true,
store: wgpu::StoreOp::Store,
},
}],
})],
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
},
);
render_pass.set_pipeline(&blit.pipeline);
@ -747,6 +778,7 @@ impl<'frame> Drop for Drawer<'frame> {
if let Some(f) = download_and_handle_screenshot {
f();
}
self.surface_texture.take().unwrap().present();
profiler
.end_frame()
@ -1280,6 +1312,49 @@ impl<'pass_ref, 'pass: 'pass_ref> TrailDrawer<'pass_ref, 'pass> {
}
}
/// Third pass drawer intermediate representation in order to store
/// the surface texture view (in case it's used).
pub struct ThirdPassDrawerPrepared<'pass, 'drawer> {
/// The texture view to render to.
view: wgpu::TextureView,
drawer: &'pass mut Drawer<'drawer>,
}
impl<'pass, 'drawer> ThirdPassDrawerPrepared<'pass, 'drawer> {
pub fn drawer(&mut self) -> ThirdPassDrawer {
let encoder = self.drawer.encoder.as_mut().unwrap();
let device = self.drawer.borrow.device;
let mut render_pass =
encoder.scoped_render_pass("third_pass", device, &wgpu::RenderPassDescriptor {
label: Some("third pass (postprocess + ui)"),
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
// If a screenshot was requested render to that as an intermediate texture
// instead
view: self
.drawer
.taking_screenshot
.as_ref()
.map_or(&self.view, |s| s.texture_view()),
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color::TRANSPARENT),
store: wgpu::StoreOp::Store,
},
})],
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
});
render_pass.set_bind_group(0, &self.drawer.globals.bind_group, &[]);
ThirdPassDrawer {
render_pass,
borrow: &self.drawer.borrow,
}
}
}
/// Third pass: postprocess + ui
#[must_use]
pub struct ThirdPassDrawer<'pass> {

View File

@ -14,7 +14,6 @@ use super::{
};
use common_base::{prof_span, prof_span_alloc};
use std::sync::Arc;
use tracing::warn;
/// All the pipelines
pub struct Pipelines {
@ -283,8 +282,9 @@ impl ShaderModules {
let mut compiler = Compiler::new().ok_or(RenderError::ErrorInitializingCompiler)?;
let mut options = CompileOptions::new().ok_or(RenderError::ErrorInitializingCompiler)?;
options.set_optimization_level(OptimizationLevel::Performance);
options.set_optimization_level(OptimizationLevel::Zero);
options.set_forced_version_profile(430, shaderc::GlslProfile::Core);
// options.set_generate_debug_info();
options.set_include_callback(move |name, _, shader_name, _| {
Ok(ResolvedInclude {
resolved_name: name.to_string(),
@ -409,20 +409,27 @@ fn create_shader_module(
.compile_into_spirv(source, kind, file_name, "main", Some(options))
.map_err(|e| (file_name, e))?;
if spv.get_num_warnings() > 0 {
warn!(
"shaderc emitted compilation warnings for {file_name}:\n\n{}",
spv.get_warning_messages()
);
}
// Uncomment me to dump shaders to files
//
// std::fs::create_dir_all("dumpped-shaders").expect("Couldn't create shader
// dumps folders");
//
// let mut file = std::fs::File::create(format!("dumpped-shaders/{}.spv",
// file_name)) .expect("Couldn't open shader out");
//
// use std::io::Write;
//
// file.write(spv.as_binary_u8())
// .expect("Couldn't write shader out");
let label = [file_name, "\n\n", source].concat();
Ok(device.create_shader_module(&wgpu::ShaderModuleDescriptor {
label: Some(&label),
source: wgpu::ShaderSource::SpirV(Cow::Borrowed(spv.as_binary())),
flags: wgpu::ShaderFlags::empty(),
// TODO: renable // flags: wgpu::ShaderFlags::VALIDATION,
}))
// let label = [file_name, "\n\n", source].concat();
#[allow(unsafe_code)]
Ok(unsafe {
device.create_shader_module_unchecked(wgpu::ShaderModuleDescriptor {
label: Some(file_name),
source: wgpu::ShaderSource::SpirV(Cow::Borrowed(spv.as_binary())),
})
})
}
/// Things needed to create a pipeline
@ -432,7 +439,7 @@ struct PipelineNeeds<'a> {
layouts: &'a Layouts,
shaders: &'a ShaderModules,
pipeline_modes: &'a PipelineModes,
sc_desc: &'a wgpu::SwapChainDescriptor,
surface_config: &'a wgpu::SurfaceConfiguration,
}
/// Creates InterfacePipelines in parallel
@ -452,7 +459,7 @@ fn create_interface_pipelines(
needs.device,
&needs.shaders.ui_vert,
&needs.shaders.ui_frag,
needs.sc_desc,
needs.surface_config,
&needs.layouts.global,
&needs.layouts.ui,
)
@ -483,7 +490,7 @@ fn create_interface_pipelines(
needs.device,
&needs.shaders.blit_vert,
&needs.shaders.blit_frag,
needs.sc_desc,
needs.surface_config,
&needs.layouts.blit,
)
},
@ -508,6 +515,7 @@ fn create_ingame_and_shadow_pipelines(
pool: &rayon::ThreadPool,
// TODO: Reduce the boilerplate in this file
tasks: [Task; 20],
format: wgpu::TextureFormat,
) -> IngameAndShadowPipelines {
prof_span!(_guard, "create_ingame_and_shadow_pipelines");
@ -516,7 +524,7 @@ fn create_ingame_and_shadow_pipelines(
layouts,
shaders,
pipeline_modes,
sc_desc,
surface_config: sc_desc,
} = needs;
let [
@ -558,6 +566,7 @@ fn create_ingame_and_shadow_pipelines(
&layouts.global,
&layouts.debug,
pipeline_modes.aa,
format,
)
},
"debug pipeline creation",
@ -573,6 +582,7 @@ fn create_ingame_and_shadow_pipelines(
&shaders.skybox_frag,
&layouts.global,
pipeline_modes.aa,
format,
)
},
"skybox pipeline creation",
@ -589,6 +599,7 @@ fn create_ingame_and_shadow_pipelines(
&layouts.global,
&layouts.figure,
pipeline_modes.aa,
format,
)
},
"figure pipeline creation",
@ -605,6 +616,7 @@ fn create_ingame_and_shadow_pipelines(
&layouts.global,
&layouts.terrain,
pipeline_modes.aa,
format,
)
},
"terrain pipeline creation",
@ -621,6 +633,7 @@ fn create_ingame_and_shadow_pipelines(
&layouts.global,
&layouts.terrain,
pipeline_modes.aa,
format,
)
},
"fluid pipeline creation",
@ -638,6 +651,7 @@ fn create_ingame_and_shadow_pipelines(
&layouts.sprite,
&layouts.terrain,
pipeline_modes.aa,
format,
)
},
"sprite pipeline creation",
@ -653,6 +667,7 @@ fn create_ingame_and_shadow_pipelines(
&shaders.lod_object_frag,
&layouts.global,
pipeline_modes.aa,
format,
)
},
"lod object pipeline creation",
@ -668,6 +683,7 @@ fn create_ingame_and_shadow_pipelines(
&shaders.particle_frag,
&layouts.global,
pipeline_modes.aa,
format,
)
},
"particle pipeline creation",
@ -699,6 +715,7 @@ fn create_ingame_and_shadow_pipelines(
&shaders.trail_frag,
&layouts.global,
pipeline_modes.aa,
format,
)
},
"trail pipeline creation",
@ -714,6 +731,7 @@ fn create_ingame_and_shadow_pipelines(
&shaders.lod_terrain_frag,
&layouts.global,
pipeline_modes.aa,
format,
)
},
"lod terrain pipeline creation",
@ -730,6 +748,7 @@ fn create_ingame_and_shadow_pipelines(
&layouts.global,
&layouts.clouds,
pipeline_modes.aa,
format,
)
},
"clouds pipeline creation",
@ -750,7 +769,7 @@ fn create_ingame_and_shadow_pipelines(
&shaders.dual_downsample_filtered_frag,
&shaders.dual_downsample_frag,
&shaders.dual_upsample_frag,
wgpu::TextureFormat::Rgba16Float,
format,
&layouts.bloom,
bloom_config,
)
@ -974,8 +993,9 @@ pub(super) fn initial_create_pipelines(
layouts: Layouts,
shaders: Shaders,
pipeline_modes: PipelineModes,
sc_desc: wgpu::SwapChainDescriptor,
surface_config: wgpu::SurfaceConfiguration,
has_shadow_views: bool,
intermediate_format: wgpu::TextureFormat,
) -> Result<
(
InterfacePipelines,
@ -999,7 +1019,7 @@ pub(super) fn initial_create_pipelines(
layouts: &layouts,
shaders: &shader_modules,
pipeline_modes: &pipeline_modes,
sc_desc: &sc_desc,
surface_config: &surface_config,
};
// Create interface pipelines while blocking the main thread
@ -1026,10 +1046,15 @@ pub(super) fn initial_create_pipelines(
layouts: &layouts,
shaders: &shader_modules,
pipeline_modes: &pipeline_modes,
sc_desc: &sc_desc,
surface_config: &surface_config,
};
let pipelines = create_ingame_and_shadow_pipelines(needs, pool, progress.create_tasks());
let pipelines = create_ingame_and_shadow_pipelines(
needs,
pool,
progress.create_tasks(),
intermediate_format,
);
pipeline_send.send(pipelines).expect("Channel disconnected");
});
@ -1046,8 +1071,9 @@ pub(super) fn recreate_pipelines(
immutable_layouts: Arc<ImmutableLayouts>,
shaders: Shaders,
pipeline_modes: PipelineModes,
sc_desc: wgpu::SwapChainDescriptor,
surface_config: wgpu::SurfaceConfiguration,
has_shadow_views: bool,
intermediate_format: wgpu::TextureFormat,
) -> PipelineCreation<
Result<
(
@ -1112,7 +1138,7 @@ pub(super) fn recreate_pipelines(
layouts: &layouts,
shaders: &shader_modules,
pipeline_modes: &pipeline_modes,
sc_desc: &sc_desc,
surface_config: &surface_config,
};
// Create interface pipelines
@ -1123,7 +1149,12 @@ pub(super) fn recreate_pipelines(
ingame,
shadow,
rain_occlusion,
} = create_ingame_and_shadow_pipelines(needs, pool, ingame_and_shadow_tasks);
} = create_ingame_and_shadow_pipelines(
needs,
pool,
ingame_and_shadow_tasks,
intermediate_format,
);
// Send them
result_send

View File

@ -60,7 +60,9 @@ impl RainOcclusionMap {
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Depth24Plus,
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::RENDER_ATTACHMENT,
usage: wgpu::TextureUsages::TEXTURE_BINDING
| wgpu::TextureUsages::RENDER_ATTACHMENT,
view_formats: &[],
};
let view = wgpu::TextureViewDescriptor {
@ -101,10 +103,12 @@ impl RainOcclusionMap {
view: &tex.view,
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Clear(1.0),
store: true,
store: wgpu::StoreOp::Store,
}),
stencil_ops: None,
}),
timestamp_writes: None,
occlusion_query_set: None,
});
queue.submit(std::iter::once(encoder.finish()));
@ -182,7 +186,8 @@ impl RainOcclusionMap {
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Depth24Plus,
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::RENDER_ATTACHMENT,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::RENDER_ATTACHMENT,
view_formats: &[],
};
let rain_occlusion_view = wgpu::TextureViewDescriptor {

View File

@ -13,7 +13,7 @@ pub struct TakeScreenshot {
// Dimensions used for copying from the screenshot texture to a buffer
width: u32,
height: u32,
bytes_per_pixel: u8,
bytes_per_pixel: u32,
// Texture format
tex_format: wgpu::TextureFormat,
}
@ -24,7 +24,7 @@ impl TakeScreenshot {
blit_layout: &blit::BlitLayout,
sampler: &wgpu::Sampler,
// Used to determine the resolution and texture format
sc_desc: &wgpu::SwapChainDescriptor,
surface_config: &wgpu::SurfaceConfiguration,
// Function that is given the image after downloading it from the GPU
// This is executed in a background thread
screenshot_fn: ScreenshotFn,
@ -32,22 +32,23 @@ impl TakeScreenshot {
let texture = device.create_texture(&wgpu::TextureDescriptor {
label: Some("screenshot tex"),
size: wgpu::Extent3d {
width: sc_desc.width,
height: sc_desc.height,
width: surface_config.width,
height: surface_config.height,
depth_or_array_layers: 1,
},
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: sc_desc.format,
usage: wgpu::TextureUsage::COPY_SRC
| wgpu::TextureUsage::SAMPLED
| wgpu::TextureUsage::RENDER_ATTACHMENT,
format: surface_config.format,
usage: wgpu::TextureUsages::COPY_SRC
| wgpu::TextureUsages::TEXTURE_BINDING
| wgpu::TextureUsages::RENDER_ATTACHMENT,
view_formats: &[],
});
let view = texture.create_view(&wgpu::TextureViewDescriptor {
label: Some("screenshot tex view"),
format: Some(sc_desc.format),
format: Some(surface_config.format),
dimension: Some(wgpu::TextureViewDimension::D2),
aspect: wgpu::TextureAspect::All,
base_mip_level: 0,
@ -58,13 +59,13 @@ impl TakeScreenshot {
let bind_group = blit_layout.bind(device, &view, sampler);
let bytes_per_pixel = sc_desc.format.describe().block_size;
let padded_bytes_per_row = padded_bytes_per_row(sc_desc.width, bytes_per_pixel);
let bytes_per_pixel = surface_config.format.block_size(None).unwrap();
let padded_bytes_per_row = padded_bytes_per_row(surface_config.width, bytes_per_pixel);
let buffer = device.create_buffer(&wgpu::BufferDescriptor {
label: Some("screenshot download buffer"),
size: (padded_bytes_per_row * sc_desc.height) as u64,
usage: wgpu::BufferUsage::COPY_DST | wgpu::BufferUsage::MAP_READ,
size: (padded_bytes_per_row * surface_config.height) as u64,
usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::MAP_READ,
mapped_at_creation: false,
});
@ -74,10 +75,10 @@ impl TakeScreenshot {
view,
buffer,
screenshot_fn,
width: sc_desc.width,
height: sc_desc.height,
width: surface_config.width,
height: surface_config.height,
bytes_per_pixel,
tex_format: sc_desc.format,
tex_format: surface_config.format,
}
}
@ -104,12 +105,13 @@ impl TakeScreenshot {
texture: &self.texture,
mip_level: 0,
origin: wgpu::Origin3d::ZERO,
aspect: wgpu::TextureAspect::All,
},
wgpu::ImageCopyBuffer {
buffer: &self.buffer,
layout: wgpu::ImageDataLayout {
offset: 0,
bytes_per_row: core::num::NonZeroU32::new(padded_bytes_per_row),
bytes_per_row: Some(padded_bytes_per_row),
rows_per_image: None,
},
},
@ -121,8 +123,10 @@ impl TakeScreenshot {
);
move || {
// Send buffer to another thread for async mapping, downloading, and passing to
// the given handler function (which probably saves it to the disk)
// TODO: Do we need a thread for this now that we handle screenshots in a
// callback from wgpu? Send buffer to another thread for async
// mapping, downloading, and passing to the given handler function
// (which probably saves it to the disk)
std::thread::Builder::new()
.name("screenshot".into())
.spawn(move || {
@ -136,100 +140,94 @@ impl TakeScreenshot {
prof_span!("download_and_handle_internal");
// Calculate padded bytes per row
let padded_bytes_per_row = padded_bytes_per_row(self.width, self.bytes_per_pixel);
let singlethread_rt = match tokio::runtime::Builder::new_current_thread().build() {
Ok(rt) => rt,
Err(err) => {
error!(?err, "Could not create tokio runtime");
return;
},
};
// Map buffer
let buffer_slice = self.buffer.slice(..);
let buffer_map_future = buffer_slice.map_async(wgpu::MapMode::Read);
let padded_buffer;
// Wait on buffer mapping
let rows = match singlethread_rt.block_on(buffer_map_future) {
// Buffer is mapped and we can read it
Ok(()) => {
// Copy to a Vec
padded_buffer = buffer_slice.get_mapped_range();
padded_buffer
.chunks(padded_bytes_per_row as usize)
.map(|padded_chunk| {
&padded_chunk[..self.width as usize * self.bytes_per_pixel as usize]
})
},
// Error
Err(err) => {
error!(
?err,
"Failed to map buffer for downloading a screenshot from the GPU"
);
return;
},
};
// Note: we don't use bytes_per_pixel here since we expect only certain formats
// below.
let bytes_per_rgb = 3;
let mut pixel_bytes =
Vec::with_capacity(self.width as usize * self.height as usize * bytes_per_rgb);
// Construct image
let image = match self.tex_format {
wgpu::TextureFormat::Bgra8UnormSrgb => {
prof_span!("copy image");
rows.for_each(|row| {
let (pixels, rest) = row.as_chunks();
assert!(
rest.is_empty(),
"Always valid because each pixel uses four bytes"
let buffer = std::sync::Arc::new(self.buffer);
let buffer2 = std::sync::Arc::clone(&buffer);
let buffer_slice = buffer.slice(..);
buffer_slice.map_async(wgpu::MapMode::Read, move |result| {
let padded_buffer;
let buffer_slice = buffer2.slice(..);
let rows = match result {
Ok(()) => {
// Copy to a Vec
padded_buffer = buffer_slice.get_mapped_range();
padded_buffer
.chunks(padded_bytes_per_row as usize)
.map(|padded_chunk| {
&padded_chunk[..self.width as usize * self.bytes_per_pixel as usize]
})
},
// Error
Err(err) => {
error!(
?err,
"Failed to map buffer for downloading a screenshot from the GPU"
);
// Swap blue and red components and drop alpha to get a RGB texture.
for &[b, g, r, _a] in pixels {
pixel_bytes.extend_from_slice(&[r, g, b])
}
});
return;
},
};
Ok(pixel_bytes)
},
wgpu::TextureFormat::Rgba8UnormSrgb => {
prof_span!("copy image");
rows.for_each(|row| {
let (pixels, rest) = row.as_chunks();
assert!(
rest.is_empty(),
"Always valid because each pixel uses four bytes"
);
// Drop alpha to get a RGB texture.
for &[r, g, b, _a] in pixels {
pixel_bytes.extend_from_slice(&[r, g, b])
}
});
// Note: we don't use bytes_per_pixel here since we expect only certain formats
// below.
let bytes_per_rgb = 3;
let mut pixel_bytes =
Vec::with_capacity(self.width as usize * self.height as usize * bytes_per_rgb);
// Construct image
let image = match self.tex_format {
wgpu::TextureFormat::Bgra8UnormSrgb => {
prof_span!("copy image");
rows.for_each(|row| {
let (pixels, rest) = row.as_chunks();
assert!(
rest.is_empty(),
"Always valid because each pixel uses four bytes"
);
// Swap blue and red components and drop alpha to get a RGB texture.
for &[b, g, r, _a] in pixels {
pixel_bytes.extend_from_slice(&[r, g, b])
}
});
Ok(pixel_bytes)
},
format => Err(format!(
"Unhandled format for screenshot texture: {:?}",
format,
)),
}
.map(|pixel_bytes| {
image::RgbImage::from_vec(self.width, self.height, pixel_bytes).expect(
"Failed to create ImageBuffer! Buffer was not large enough. This should not occur",
)
Ok(pixel_bytes)
},
wgpu::TextureFormat::Rgba8UnormSrgb => {
prof_span!("copy image");
rows.for_each(|row| {
let (pixels, rest) = row.as_chunks();
assert!(
rest.is_empty(),
"Always valid because each pixel uses four bytes"
);
// Drop alpha to get a RGB texture.
for &[r, g, b, _a] in pixels {
pixel_bytes.extend_from_slice(&[r, g, b])
}
});
Ok(pixel_bytes)
},
format => Err(format!(
"Unhandled format for screenshot texture: {:?}",
format,
)),
}
.map(|pixel_bytes| {
image::RgbImage::from_vec(self.width, self.height, pixel_bytes).expect(
"Failed to create ImageBuffer! Buffer was not large enough. This should not \
occur",
)
});
// Call supplied handler
(self.screenshot_fn)(image);
});
// Call supplied handler
(self.screenshot_fn)(image);
}
}
// Graphics API requires a specific alignment for buffer copies
fn padded_bytes_per_row(width: u32, bytes_per_pixel: u8) -> u32 {
fn padded_bytes_per_row(width: u32, bytes_per_pixel: u32) -> u32 {
let align = wgpu::COPY_BYTES_PER_ROW_ALIGNMENT;
let unpadded_bytes_per_row = width * bytes_per_pixel as u32;
let unpadded_bytes_per_row = width * bytes_per_pixel;
let padding = (align - unpadded_bytes_per_row % align) % align;
unpadded_bytes_per_row + padding
}

View File

@ -81,7 +81,9 @@ impl ShadowMap {
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Depth24Plus,
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::RENDER_ATTACHMENT,
usage: wgpu::TextureUsages::TEXTURE_BINDING
| wgpu::TextureUsages::RENDER_ATTACHMENT,
view_formats: &[],
};
let view = wgpu::TextureViewDescriptor {
@ -125,10 +127,12 @@ impl ShadowMap {
view: &tex.view,
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Clear(1.0),
store: true,
store: wgpu::StoreOp::Store,
}),
stencil_ops: None,
}),
timestamp_writes: None,
occlusion_query_set: None,
});
};
clear(&cube_tex);
@ -208,7 +212,8 @@ impl ShadowMap {
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Depth24Plus,
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::RENDER_ATTACHMENT,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::RENDER_ATTACHMENT,
view_formats: &[],
};
let point_shadow_view = wgpu::TextureViewDescriptor {
@ -233,7 +238,8 @@ impl ShadowMap {
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Depth24Plus,
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::RENDER_ATTACHMENT,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::RENDER_ATTACHMENT,
view_formats: &[],
};
let directed_shadow_view = wgpu::TextureViewDescriptor {

View File

@ -1,5 +1,4 @@
use super::RenderError;
use core::num::NonZeroU32;
use image::DynamicImage;
use wgpu::Extent3d;
@ -55,7 +54,8 @@ impl Texture {
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format,
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
view_formats: &[],
});
queue.write_texture(
@ -63,12 +63,13 @@ impl Texture {
texture: &tex,
mip_level: 0,
origin: wgpu::Origin3d::ZERO,
aspect: wgpu::TextureAspect::All,
},
buffer.as_slice(),
wgpu::ImageDataLayout {
offset: 0,
bytes_per_row: NonZeroU32::new(image.width() * bytes_per_pixel),
rows_per_image: NonZeroU32::new(image.height()),
bytes_per_row: Some(image.width() * bytes_per_pixel),
rows_per_image: Some(image.height()),
},
Extent3d {
width: image.width(),
@ -128,7 +129,8 @@ impl Texture {
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Rgba8UnormSrgb,
// TODO: nondynamic version doesn't seeem to have different usage, unify code?
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
view_formats: &[],
};
let sampler_info = wgpu::SamplerDescriptor {
@ -184,7 +186,7 @@ impl Texture {
let byte_len = size.width as usize
* size.height as usize
* size.depth_or_array_layers as usize
* self.format.describe().block_size as usize;
* self.format.block_size(None).unwrap() as usize;
let zeros = vec![0; byte_len];
self.update(queue, [0, 0], [size.width, size.height], &zeros);
@ -193,7 +195,7 @@ impl Texture {
/// Update a texture with the given data (used for updating the glyph cache
/// texture).
pub fn update(&self, queue: &wgpu::Queue, offset: [u32; 2], size: [u32; 2], data: &[u8]) {
let bytes_per_pixel = self.format.describe().block_size as u32;
let bytes_per_pixel = self.format.block_size(None).unwrap() as u32;
debug_assert_eq!(
data.len(),
@ -209,12 +211,13 @@ impl Texture {
y: offset[1],
z: 0,
},
aspect: wgpu::TextureAspect::All,
},
data,
wgpu::ImageDataLayout {
offset: 0,
bytes_per_row: NonZeroU32::new(size[0] * bytes_per_pixel),
rows_per_image: NonZeroU32::new(size[1]),
bytes_per_row: Some(size[0] * bytes_per_pixel),
rows_per_image: Some(size[1]),
},
Extent3d {
width: size[0],

View File

@ -782,7 +782,7 @@ impl<V: RectRasterableVol> Terrain<V> {
.map(|fmt| {
renderer.create_texture_raw(
&wgpu::TextureDescriptor {
label: Some("Terrain atlas texture"),
label: Some("Atlas texture"),
size: wgpu::Extent3d {
width: max_texture_size,
height: max_texture_size,
@ -792,10 +792,11 @@ impl<V: RectRasterableVol> Terrain<V> {
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: fmt,
usage: wgpu::TextureUsage::COPY_DST | wgpu::TextureUsage::SAMPLED,
usage: wgpu::TextureUsages::COPY_DST | wgpu::TextureUsages::TEXTURE_BINDING,
view_formats: &[],
},
&wgpu::TextureViewDescriptor {
label: Some("Terrain atlas texture view"),
label: Some("Atlas texture view"),
format: Some(fmt),
dimension: Some(wgpu::TextureViewDimension::D2),
aspect: wgpu::TextureAspect::All,
@ -805,7 +806,7 @@ impl<V: RectRasterableVol> Terrain<V> {
array_layer_count: None,
},
&wgpu::SamplerDescriptor {
label: Some("Terrain atlas texture sampler"),
label: Some("Atlas sampler"),
address_mode_u: wgpu::AddressMode::ClampToEdge,
address_mode_v: wgpu::AddressMode::ClampToEdge,
address_mode_w: wgpu::AddressMode::ClampToEdge,

View File

@ -2146,7 +2146,8 @@ impl PlayState for SessionState {
// PostProcess and UI
{
prof_span!("post-process and ui");
let mut third_pass = drawer.third_pass();
let mut third_pass_prepared = drawer.prepare_third_pass();
let mut third_pass = third_pass_prepared.drawer();
third_pass.draw_postprocess();
// Draw the UI to the screen
if let Some(mut ui_drawer) = third_pass.draw_ui() {

View File

@ -695,7 +695,7 @@ fn create_image_texture(
// TODO: Right now we have to manually clear images to workaround AMD DX bug,
// for this we use Queue::write_texture which needs this usage. I think this
// may be fixed in newer wgpu versions that auto-clear the texture.
let workaround_usage = wgpu::TextureUsage::COPY_DST;
let workaround_usage = wgpu::TextureUsages::COPY_DST;
let tex_info = wgpu::TextureDescriptor {
label: None,
size: wgpu::Extent3d {
@ -707,10 +707,11 @@ fn create_image_texture(
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Rgba8UnormSrgb,
usage: wgpu::TextureUsage::RENDER_ATTACHMENT // GPU premultiply
| wgpu::TextureUsage::COPY_DST // CPU premultiply
| wgpu::TextureUsage::SAMPLED // using image in ui rendering
usage: wgpu::TextureUsages::RENDER_ATTACHMENT // GPU premultiply
| wgpu::TextureUsages::COPY_DST // CPU premultiply
| wgpu::TextureUsages::TEXTURE_BINDING // using image in ui rendering
| workaround_usage,
view_formats: &[],
};
let view_info = wgpu::TextureViewDescriptor {
format: Some(tex_info.format),

View File

@ -1039,17 +1039,12 @@ impl Window {
pub fn is_cursor_grabbed(&self) -> bool { self.cursor_grabbed }
pub fn grab_cursor(&mut self, grab: bool) {
use winit::window::CursorGrabMode;
self.cursor_grabbed = grab;
self.window.set_cursor_visible(!grab);
let res = if grab {
self.window
.set_cursor_grab(CursorGrabMode::Locked)
.or_else(|_e| self.window.set_cursor_grab(CursorGrabMode::Confined))
} else {
self.window.set_cursor_grab(CursorGrabMode::None)
};
let res = self.window.set_cursor_grab(match grab {
true => winit::window::CursorGrabMode::Confined,
false => winit::window::CursorGrabMode::None,
});
if let Err(e) = res {
error!(?e, ?grab, "Failed to toggle cursor grab");