Upgrade to wgpu 0.11 (#2933)

Upgrades both the old and new renderer to wgpu 0.11 (and naga 0.7). This builds on @zicklag's work here #2556.

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
This commit is contained in:
Carter Anderson 2021-10-08 19:55:24 +00:00
parent 40fccd29ca
commit 43e8a156fb
44 changed files with 286 additions and 267 deletions

View file

@ -14,6 +14,7 @@ keywords = ["game", "engine", "gamedev", "graphics", "bevy"]
license = "MIT OR Apache-2.0"
readme = "README.md"
repository = "https://github.com/bevyengine/bevy"
resolver = "2"
[workspace]
exclude = ["benches"]

View file

@ -7,7 +7,7 @@ use crate::{
LoadOp, Operations, PassDescriptor, RenderPassColorAttachment,
RenderPassDepthStencilAttachment, TextureAttachment,
},
texture::{Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsage},
texture::{Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages},
Color,
};
use bevy_ecs::{reflect::ReflectComponent, world::World};
@ -126,7 +126,7 @@ pub(crate) fn add_base_graph(config: &BaseRenderGraphConfig, world: &mut World)
dimension: TextureDimension::D2,
format: TextureFormat::Depth32Float, /* PERF: vulkan docs recommend using 24
* bit depth for better performance */
usage: TextureUsage::OUTPUT_ATTACHMENT,
usage: TextureUsages::OUTPUT_ATTACHMENT,
},
),
);
@ -220,7 +220,7 @@ pub(crate) fn add_base_graph(config: &BaseRenderGraphConfig, world: &mut World)
sample_count: msaa.samples,
dimension: TextureDimension::D2,
format: TextureFormat::default(),
usage: TextureUsage::OUTPUT_ATTACHMENT,
usage: TextureUsages::OUTPUT_ATTACHMENT,
},
),
);

View file

@ -52,7 +52,7 @@ impl Node for WindowSwapChainNode {
let render_resource_context = render_context.resources_mut();
// create window swapchain when window is resized or created
// reconfigure surface window is resized or created
if self
.window_created_event_reader
.iter(window_created_events)
@ -62,10 +62,10 @@ impl Node for WindowSwapChainNode {
.iter(window_resized_events)
.any(|e| e.id == window.id())
{
render_resource_context.create_swap_chain(window);
render_resource_context.configure_surface(window);
}
let swap_chain_texture = render_resource_context.next_swap_chain_texture(window);
let swap_chain_texture = render_resource_context.next_surface_frame(window);
output.set(
WINDOW_TEXTURE,
RenderResourceId::Texture(swap_chain_texture),

View file

@ -31,15 +31,15 @@ impl HeadlessRenderResourceContext {
}
impl RenderResourceContext for HeadlessRenderResourceContext {
fn create_swap_chain(&self, _window: &Window) {}
fn configure_surface(&self, _window: &Window) {}
fn next_swap_chain_texture(&self, _window: &Window) -> TextureId {
fn next_surface_frame(&self, _window: &Window) -> TextureId {
TextureId::new()
}
fn drop_swap_chain_texture(&self, _render_resource: TextureId) {}
fn drop_surface_frame(&self, _render_resource: TextureId) {}
fn drop_all_swap_chain_textures(&self) {}
fn drop_all_surface_frames(&self) {}
fn create_sampler(&self, _sampler_descriptor: &SamplerDescriptor) -> SamplerId {
SamplerId::new()

View file

@ -12,10 +12,10 @@ use downcast_rs::{impl_downcast, Downcast};
use std::ops::Range;
pub trait RenderResourceContext: Downcast + Send + Sync + 'static {
fn create_swap_chain(&self, window: &Window);
fn next_swap_chain_texture(&self, window: &Window) -> TextureId;
fn drop_swap_chain_texture(&self, resource: TextureId);
fn drop_all_swap_chain_textures(&self);
fn configure_surface(&self, window: &Window);
fn next_surface_frame(&self, window: &Window) -> TextureId;
fn drop_surface_frame(&self, resource: TextureId);
fn drop_all_surface_frames(&self);
fn create_sampler(&self, sampler_descriptor: &SamplerDescriptor) -> SamplerId;
fn create_texture(&self, texture_descriptor: TextureDescriptor) -> TextureId;
fn create_buffer(&self, buffer_info: BufferInfo) -> BufferId;

View file

@ -106,9 +106,9 @@ pub fn glsl_to_spirv(
impl Into<shaderc::ShaderKind> for ShaderStage {
fn into(self) -> shaderc::ShaderKind {
match self {
ShaderStage::Vertex => shaderc::ShaderKind::Vertex,
ShaderStage::Fragment => shaderc::ShaderKind::Fragment,
ShaderStage::Compute => shaderc::ShaderKind::Compute,
ShaderStages::VERTEX => shaderc::ShaderKind::Vertex,
ShaderStages::FRAGMENT => shaderc::ShaderKind::Fragment,
ShaderStages::COMPUTE => shaderc::ShaderKind::Compute,
}
}
}

View file

@ -1,4 +1,4 @@
use super::{Extent3d, Texture, TextureDimension, TextureFormat, TextureUsage};
use super::{Extent3d, Texture, TextureDimension, TextureFormat, TextureUsages};
/// Describes a texture
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
@ -8,7 +8,7 @@ pub struct TextureDescriptor {
pub sample_count: u32,
pub dimension: TextureDimension,
pub format: TextureFormat,
pub usage: TextureUsage,
pub usage: TextureUsages,
}
impl From<&Texture> for TextureDescriptor {
@ -19,7 +19,7 @@ impl From<&Texture> for TextureDescriptor {
sample_count: 1,
dimension: texture.dimension,
format: texture.format,
usage: TextureUsage::SAMPLED | TextureUsage::COPY_DST,
usage: TextureUsages::SAMPLED | TextureUsages::COPY_DST,
}
}
}
@ -36,7 +36,7 @@ impl Default for TextureDescriptor {
sample_count: 1,
dimension: TextureDimension::D2,
format: TextureFormat::Rgba8UnormSrgb,
usage: TextureUsage::SAMPLED | TextureUsage::COPY_DST,
usage: TextureUsages::SAMPLED | TextureUsages::COPY_DST,
}
}
}

View file

@ -276,7 +276,7 @@ impl Default for TextureFormat {
bitflags::bitflags! {
#[repr(transparent)]
pub struct TextureUsage: u32 {
pub struct TextureUsages: u32 {
const COPY_SRC = 1;
const COPY_DST = 2;
const SAMPLED = 4;

View file

@ -21,7 +21,7 @@ struct Rect {
vec2 end;
};
layout(set = 1, binding = 1) buffer TextureAtlas_textures {
layout(set = 1, binding = 1) readonly buffer TextureAtlas_textures {
Rect[] Textures;
};

View file

@ -29,7 +29,7 @@ bevy_winit = { path = "../bevy_winit", optional = true, version = "0.5.0" }
bevy_utils = { path = "../bevy_utils", version = "0.5.0" }
# other
wgpu = "0.9"
wgpu = { version = "0.11.0", features = ["spirv"] }
futures-lite = "1.4.0"
crossbeam-channel = "0.5.0"
crossbeam-utils = "0.8.1"

View file

@ -29,9 +29,7 @@ impl WgpuResourceDiagnosticsPlugin {
DiagnosticId::from_u128(305855369913076220671125671543184691267);
pub const SHADER_MODULES: DiagnosticId =
DiagnosticId::from_u128(287681470908132753275843248383768232237);
pub const SWAP_CHAINS: DiagnosticId =
DiagnosticId::from_u128(199253035828743332241465305105689014605);
pub const SWAP_CHAIN_OUTPUTS: DiagnosticId =
pub const SURFACE_FRAMES: DiagnosticId =
DiagnosticId::from_u128(112048874168736161226721327099863374234);
pub const TEXTURES: DiagnosticId =
DiagnosticId::from_u128(305955424195390184883220102469231911115);
@ -47,10 +45,8 @@ impl WgpuResourceDiagnosticsPlugin {
10,
));
diagnostics.add(Diagnostic::new(Self::SWAP_CHAINS, "swap_chains", 10));
diagnostics.add(Diagnostic::new(
Self::SWAP_CHAIN_OUTPUTS,
Self::SURFACE_FRAMES,
"swap_chain_outputs",
10,
));
@ -99,19 +95,10 @@ impl WgpuResourceDiagnosticsPlugin {
);
diagnostics.add_measurement(
Self::SWAP_CHAINS,
Self::SURFACE_FRAMES,
render_resource_context
.resources
.window_swap_chains
.read()
.len() as f64,
);
diagnostics.add_measurement(
Self::SWAP_CHAIN_OUTPUTS,
render_resource_context
.resources
.swap_chain_frames
.surface_textures
.read()
.len() as f64,
);

View file

@ -29,15 +29,12 @@ pub enum WgpuFeature {
TimestampQuery,
PipelineStatisticsQuery,
MappablePrimaryBuffers,
SampledTextureBindingArray,
SampledTextureArrayDynamicIndexing,
SampledTextureArrayNonUniformIndexing,
UnsizedBindingArray,
MultiDrawIndirect,
MultiDrawIndirectCount,
PushConstants,
AddressModeClampToBorder,
NonFillPolygonMode,
PolygonModeLine,
TextureCompressionEtc2,
TextureCompressionAstcLdr,
TextureAdapterSpecificFormatFeatures,
@ -70,6 +67,8 @@ pub struct WgpuLimits {
pub max_vertex_buffers: u32,
pub max_vertex_attributes: u32,
pub max_vertex_buffer_array_stride: u32,
pub min_storage_buffer_offset_alignment: u32,
pub min_uniform_buffer_offset_alignment: u32,
}
impl Default for WgpuLimits {
@ -96,6 +95,8 @@ impl Default for WgpuLimits {
max_vertex_buffers: default.max_vertex_buffers,
max_vertex_attributes: default.max_vertex_attributes,
max_vertex_buffer_array_stride: default.max_vertex_buffer_array_stride,
min_storage_buffer_offset_alignment: default.min_storage_buffer_offset_alignment,
min_uniform_buffer_offset_alignment: default.min_uniform_buffer_offset_alignment,
}
}
}

View file

@ -231,8 +231,15 @@ fn get_texture_view<'a>(
panic!("Color attachment {} does not exist.", name);
}
},
TextureAttachment::Id(render_resource) => refs.textures.get(render_resource).unwrap_or_else(|| &refs.swap_chain_frames.get(render_resource).unwrap().output.view),
TextureAttachment::Input(_) => panic!("Encountered unset `TextureAttachment::Input`. The `RenderGraph` executor should always set `TextureAttachment::Inputs` to `TextureAttachment::RenderResource` before running. This is a bug, please report it!"),
TextureAttachment::Id(render_resource) => refs
.textures
.get(render_resource)
.unwrap_or_else(|| &refs.surface_textures.get(render_resource).unwrap().0),
TextureAttachment::Input(_) => panic!(
"Encountered unset `TextureAttachment::Input`. The `RenderGraph` executor should \
always set `TextureAttachment::Inputs` to `TextureAttachment::RenderResource` before \
running. This is a bug, please report it!"
),
}
}

View file

@ -31,7 +31,8 @@ pub struct WgpuRenderResourceContext {
}
pub const COPY_BYTES_PER_ROW_ALIGNMENT: usize = wgpu::COPY_BYTES_PER_ROW_ALIGNMENT as usize;
pub const BIND_BUFFER_ALIGNMENT: usize = wgpu::BIND_BUFFER_ALIGNMENT as usize;
// TODO: fix this?
pub const BIND_BUFFER_ALIGNMENT: usize = 256;
pub const COPY_BUFFER_ALIGNMENT: usize = wgpu::COPY_BUFFER_ALIGNMENT as usize;
pub const PUSH_CONSTANT_ALIGNMENT: u32 = wgpu::PUSH_CONSTANT_ALIGNMENT;
@ -94,6 +95,7 @@ impl WgpuRenderResourceContext {
y: source_origin[1],
z: source_origin[2],
},
aspect: wgpu::TextureAspect::All,
},
wgpu::ImageCopyTexture {
texture: destination,
@ -103,6 +105,7 @@ impl WgpuRenderResourceContext {
y: destination_origin[1],
z: destination_origin[2],
},
aspect: wgpu::TextureAspect::All,
},
size.wgpu_into(),
)
@ -134,6 +137,7 @@ impl WgpuRenderResourceContext {
y: source_origin[1],
z: source_origin[2],
},
aspect: wgpu::TextureAspect::All,
},
wgpu::ImageCopyBuffer {
buffer: destination,
@ -181,6 +185,7 @@ impl WgpuRenderResourceContext {
y: destination_origin[1],
z: destination_origin[2],
},
aspect: wgpu::TextureAspect::All,
},
size.wgpu_into(),
);
@ -206,11 +211,11 @@ impl WgpuRenderResourceContext {
let shader_stage = if binding.shader_stage
== BindingShaderStage::VERTEX | BindingShaderStage::FRAGMENT
{
wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT
wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT
} else if binding.shader_stage == BindingShaderStage::VERTEX {
wgpu::ShaderStage::VERTEX
wgpu::ShaderStages::VERTEX
} else if binding.shader_stage == BindingShaderStage::FRAGMENT {
wgpu::ShaderStage::FRAGMENT
wgpu::ShaderStages::FRAGMENT
} else {
panic!("Invalid binding shader stage.")
};
@ -230,14 +235,15 @@ impl WgpuRenderResourceContext {
bind_group_layouts.insert(descriptor.id, bind_group_layout);
}
fn try_next_swap_chain_texture(&self, window_id: bevy_window::WindowId) -> Option<TextureId> {
let mut window_swap_chains = self.resources.window_swap_chains.write();
let mut swap_chain_outputs = self.resources.swap_chain_frames.write();
fn try_next_surface_frame(&self, window_id: bevy_window::WindowId) -> Option<TextureId> {
let mut window_surfaces = self.resources.window_surfaces.write();
let mut surface_frames = self.resources.surface_textures.write();
let window_swap_chain = window_swap_chains.get_mut(&window_id).unwrap();
let next_texture = window_swap_chain.get_current_frame().ok()?;
let window_surface = window_surfaces.get_mut(&window_id).unwrap();
let next_texture = window_surface.get_current_texture().ok()?;
let view = next_texture.texture.create_view(&Default::default());
let id = TextureId::new();
swap_chain_outputs.insert(id, next_texture);
surface_frames.insert(id, (view, next_texture));
Some(id)
}
}
@ -339,7 +345,6 @@ impl RenderResourceContext for WgpuRenderResourceContext {
.create_shader_module(&wgpu::ShaderModuleDescriptor {
label: None,
source: wgpu::ShaderSource::SpirV(spirv),
flags: Default::default(),
});
shader_modules.insert(shader_handle.clone_weak(), shader_module);
}
@ -358,43 +363,39 @@ impl RenderResourceContext for WgpuRenderResourceContext {
self.create_shader_module_from_source(shader_handle, shader);
}
fn create_swap_chain(&self, window: &Window) {
fn configure_surface(&self, window: &Window) {
let surfaces = self.resources.window_surfaces.read();
let mut window_swap_chains = self.resources.window_swap_chains.write();
let swap_chain_descriptor: wgpu::SwapChainDescriptor = window.wgpu_into();
let surface_configuration: wgpu::SurfaceConfiguration = window.wgpu_into();
let surface = surfaces
.get(&window.id())
.expect("No surface found for window.");
let swap_chain = self
.device
.create_swap_chain(surface, &swap_chain_descriptor);
window_swap_chains.insert(window.id(), swap_chain);
surface.configure(&self.device, &surface_configuration);
}
fn next_swap_chain_texture(&self, window: &bevy_window::Window) -> TextureId {
if let Some(texture_id) = self.try_next_swap_chain_texture(window.id()) {
fn next_surface_frame(&self, window: &bevy_window::Window) -> TextureId {
if let Some(texture_id) = self.try_next_surface_frame(window.id()) {
texture_id
} else {
self.resources
.window_swap_chains
.write()
.remove(&window.id());
self.create_swap_chain(window);
self.try_next_swap_chain_texture(window.id())
self.resources.window_surfaces.write().remove(&window.id());
self.configure_surface(window);
self.try_next_surface_frame(window.id())
.expect("Failed to acquire next swap chain texture!")
}
}
fn drop_swap_chain_texture(&self, texture: TextureId) {
let mut swap_chain_outputs = self.resources.swap_chain_frames.write();
swap_chain_outputs.remove(&texture);
fn drop_surface_frame(&self, texture: TextureId) {
let mut surface_frames = self.resources.surface_textures.write();
surface_frames.remove(&texture);
}
fn drop_all_swap_chain_textures(&self) {
let mut swap_chain_outputs = self.resources.swap_chain_frames.write();
swap_chain_outputs.clear();
fn drop_all_surface_frames(&self) {
let mut surface_frames = self.resources.surface_textures.write();
for (_, (_, texture)) in surface_frames.drain() {
texture.present();
}
surface_frames.clear();
}
fn set_asset_resource_untyped(

View file

@ -24,13 +24,13 @@ pub struct WgpuRenderer {
impl WgpuRenderer {
pub async fn new(options: WgpuOptions) -> Self {
let backend = match options.backend {
WgpuBackend::Auto => wgpu::BackendBit::PRIMARY,
WgpuBackend::Vulkan => wgpu::BackendBit::VULKAN,
WgpuBackend::Metal => wgpu::BackendBit::METAL,
WgpuBackend::Dx12 => wgpu::BackendBit::DX12,
WgpuBackend::Dx11 => wgpu::BackendBit::DX11,
WgpuBackend::Gl => wgpu::BackendBit::GL,
WgpuBackend::BrowserWgpu => wgpu::BackendBit::BROWSER_WEBGPU,
WgpuBackend::Auto => wgpu::Backends::PRIMARY,
WgpuBackend::Vulkan => wgpu::Backends::VULKAN,
WgpuBackend::Metal => wgpu::Backends::METAL,
WgpuBackend::Dx12 => wgpu::Backends::DX12,
WgpuBackend::Dx11 => wgpu::Backends::DX11,
WgpuBackend::Gl => wgpu::Backends::GL,
WgpuBackend::BrowserWgpu => wgpu::Backends::BROWSER_WEBGPU,
};
let instance = wgpu::Instance::new(backend);
@ -42,6 +42,7 @@ impl WgpuRenderer {
WgpuPowerOptions::LowPower => wgpu::PowerPreference::LowPower,
},
compatible_surface: None,
..Default::default()
})
.await
.expect("Unable to find a GPU! Make sure you have installed required drivers!");
@ -56,12 +57,14 @@ impl WgpuRenderer {
#[cfg(not(feature = "trace"))]
let trace_path = None;
let adapter_limits = adapter.limits();
let (device, queue) = adapter
.request_device(
&wgpu::DeviceDescriptor {
label: options.device_label.as_ref().map(|a| a.as_ref()),
features: options.features.wgpu_into(),
limits: options.limits.wgpu_into(),
limits: adapter_limits,
},
trace_path,
)
@ -129,7 +132,7 @@ impl WgpuRenderer {
let render_resource_context = world
.get_resource::<Box<dyn RenderResourceContext>>()
.unwrap();
render_resource_context.drop_all_swap_chain_textures();
render_resource_context.drop_all_surface_frames();
render_resource_context.remove_stale_bind_groups();
}
}

View file

@ -47,7 +47,8 @@ pub struct WgpuBindGroupInfo {
pub struct WgpuResourcesReadLock<'a> {
pub buffers: RwLockReadGuard<'a, HashMap<BufferId, Arc<wgpu::Buffer>>>,
pub textures: RwLockReadGuard<'a, HashMap<TextureId, wgpu::TextureView>>,
pub swap_chain_frames: RwLockReadGuard<'a, HashMap<TextureId, wgpu::SwapChainFrame>>,
pub surface_textures:
RwLockReadGuard<'a, HashMap<TextureId, (wgpu::TextureView, wgpu::SurfaceTexture)>>,
pub render_pipelines:
RwLockReadGuard<'a, HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>>,
pub bind_groups: RwLockReadGuard<'a, HashMap<BindGroupDescriptorId, WgpuBindGroupInfo>>,
@ -59,7 +60,7 @@ impl<'a> WgpuResourcesReadLock<'a> {
WgpuResourceRefs {
buffers: &self.buffers,
textures: &self.textures,
swap_chain_frames: &self.swap_chain_frames,
surface_textures: &self.surface_textures,
render_pipelines: &self.render_pipelines,
bind_groups: &self.bind_groups,
used_bind_group_sender: &self.used_bind_group_sender,
@ -73,7 +74,7 @@ impl<'a> WgpuResourcesReadLock<'a> {
pub struct WgpuResourceRefs<'a> {
pub buffers: &'a HashMap<BufferId, Arc<wgpu::Buffer>>,
pub textures: &'a HashMap<TextureId, wgpu::TextureView>,
pub swap_chain_frames: &'a HashMap<TextureId, wgpu::SwapChainFrame>,
pub surface_textures: &'a HashMap<TextureId, (wgpu::TextureView, wgpu::SurfaceTexture)>,
pub render_pipelines: &'a HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>,
pub bind_groups: &'a HashMap<BindGroupDescriptorId, WgpuBindGroupInfo>,
pub used_bind_group_sender: &'a Sender<BindGroupId>,
@ -84,8 +85,8 @@ pub struct WgpuResources {
pub buffer_infos: Arc<RwLock<HashMap<BufferId, BufferInfo>>>,
pub texture_descriptors: Arc<RwLock<HashMap<TextureId, TextureDescriptor>>>,
pub window_surfaces: Arc<RwLock<HashMap<WindowId, wgpu::Surface>>>,
pub window_swap_chains: Arc<RwLock<HashMap<WindowId, wgpu::SwapChain>>>,
pub swap_chain_frames: Arc<RwLock<HashMap<TextureId, wgpu::SwapChainFrame>>>,
pub surface_textures:
Arc<RwLock<HashMap<TextureId, (wgpu::TextureView, wgpu::SurfaceTexture)>>>,
pub buffers: Arc<RwLock<HashMap<BufferId, Arc<wgpu::Buffer>>>>,
pub texture_views: Arc<RwLock<HashMap<TextureId, wgpu::TextureView>>>,
pub textures: Arc<RwLock<HashMap<TextureId, wgpu::Texture>>>,
@ -103,7 +104,7 @@ impl WgpuResources {
WgpuResourcesReadLock {
buffers: self.buffers.read(),
textures: self.texture_views.read(),
swap_chain_frames: self.swap_chain_frames.read(),
surface_textures: self.surface_textures.read(),
render_pipelines: self.render_pipelines.read(),
bind_groups: self.bind_groups.read(),
used_bind_group_sender: self.bind_group_counter.used_bind_group_sender.clone(),

View file

@ -13,7 +13,7 @@ use bevy_render::{
texture::{
AddressMode, Extent3d, FilterMode, SamplerBorderColor, SamplerDescriptor,
StorageTextureAccess, TextureDescriptor, TextureDimension, TextureFormat,
TextureSampleType, TextureUsage, TextureViewDimension,
TextureSampleType, TextureUsages, TextureViewDimension,
},
};
use bevy_window::Window;
@ -83,11 +83,11 @@ impl WgpuFrom<&VertexAttribute> for wgpu::VertexAttribute {
}
}
impl WgpuFrom<InputStepMode> for wgpu::InputStepMode {
impl WgpuFrom<InputStepMode> for wgpu::VertexStepMode {
fn from(val: InputStepMode) -> Self {
match val {
InputStepMode::Vertex => wgpu::InputStepMode::Vertex,
InputStepMode::Instance => wgpu::InputStepMode::Instance,
InputStepMode::Vertex => wgpu::VertexStepMode::Vertex,
InputStepMode::Instance => wgpu::VertexStepMode::Instance,
}
}
}
@ -95,7 +95,7 @@ impl WgpuFrom<InputStepMode> for wgpu::InputStepMode {
#[derive(Clone, Debug)]
pub struct OwnedWgpuVertexBufferLayout {
pub array_stride: wgpu::BufferAddress,
pub step_mode: wgpu::InputStepMode,
pub step_mode: wgpu::VertexStepMode,
pub attributes: Vec<wgpu::VertexAttribute>,
}
@ -137,9 +137,9 @@ impl WgpuFrom<Color> for wgpu::Color {
}
}
impl WgpuFrom<BufferUsage> for wgpu::BufferUsage {
impl WgpuFrom<BufferUsage> for wgpu::BufferUsages {
fn from(val: BufferUsage) -> Self {
wgpu::BufferUsage::from_bits(val.bits()).unwrap()
wgpu::BufferUsages::from_bits(val.bits()).unwrap()
}
}
@ -190,7 +190,9 @@ impl WgpuFrom<&BindType> for wgpu::BindingType {
} => wgpu::BindingType::Buffer {
ty: BufferBindingType::Uniform,
has_dynamic_offset: *has_dynamic_offset,
min_binding_size: bind_type.get_uniform_size().and_then(wgpu::BufferSize::new),
// FIXME: The line below cause a validation error
// min_binding_size: bind_type.get_uniform_size().and_then(wgpu::BufferSize::new),
min_binding_size: None,
},
BindType::StorageBuffer {
has_dynamic_offset,
@ -200,7 +202,9 @@ impl WgpuFrom<&BindType> for wgpu::BindingType {
read_only: *readonly,
},
has_dynamic_offset: *has_dynamic_offset,
min_binding_size: bind_type.get_uniform_size().and_then(wgpu::BufferSize::new),
// FIXME: The line below cause a validation error
// min_binding_size: bind_type.get_uniform_size().and_then(wgpu::BufferSize::new),
min_binding_size: None,
},
BindType::Texture {
view_dimension,
@ -346,9 +350,9 @@ impl WgpuFrom<TextureFormat> for wgpu::TextureFormat {
}
}
impl WgpuFrom<TextureUsage> for wgpu::TextureUsage {
fn from(val: TextureUsage) -> Self {
wgpu::TextureUsage::from_bits(val.bits()).unwrap()
impl WgpuFrom<TextureUsages> for wgpu::TextureUsages {
fn from(val: TextureUsages) -> Self {
wgpu::TextureUsages::from_bits(val.bits()).unwrap()
}
}
@ -526,9 +530,9 @@ impl WgpuFrom<PrimitiveState> for wgpu::PrimitiveState {
}
}
impl WgpuFrom<ColorWrite> for wgpu::ColorWrite {
impl WgpuFrom<ColorWrite> for wgpu::ColorWrites {
fn from(val: ColorWrite) -> Self {
wgpu::ColorWrite::from_bits(val.bits()).unwrap()
wgpu::ColorWrites::from_bits(val.bits()).unwrap()
}
}
@ -640,10 +644,10 @@ impl WgpuFrom<SamplerBorderColor> for wgpu::SamplerBorderColor {
}
}
impl WgpuFrom<&Window> for wgpu::SwapChainDescriptor {
impl WgpuFrom<&Window> for wgpu::SurfaceConfiguration {
fn from(window: &Window) -> Self {
wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::RENDER_ATTACHMENT,
wgpu::SurfaceConfiguration {
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
format: TextureFormat::default().wgpu_into(),
width: window.physical_width().max(1),
height: window.physical_height().max(1),
@ -664,21 +668,12 @@ impl WgpuFrom<WgpuFeature> for wgpu::Features {
WgpuFeature::TimestampQuery => wgpu::Features::TIMESTAMP_QUERY,
WgpuFeature::PipelineStatisticsQuery => wgpu::Features::PIPELINE_STATISTICS_QUERY,
WgpuFeature::MappablePrimaryBuffers => wgpu::Features::MAPPABLE_PRIMARY_BUFFERS,
WgpuFeature::SampledTextureBindingArray => {
wgpu::Features::SAMPLED_TEXTURE_BINDING_ARRAY
}
WgpuFeature::SampledTextureArrayDynamicIndexing => {
wgpu::Features::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING
}
WgpuFeature::SampledTextureArrayNonUniformIndexing => {
wgpu::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
}
WgpuFeature::UnsizedBindingArray => wgpu::Features::UNSIZED_BINDING_ARRAY,
WgpuFeature::MultiDrawIndirect => wgpu::Features::MULTI_DRAW_INDIRECT,
WgpuFeature::MultiDrawIndirectCount => wgpu::Features::MULTI_DRAW_INDIRECT_COUNT,
WgpuFeature::PushConstants => wgpu::Features::PUSH_CONSTANTS,
WgpuFeature::AddressModeClampToBorder => wgpu::Features::ADDRESS_MODE_CLAMP_TO_BORDER,
WgpuFeature::NonFillPolygonMode => wgpu::Features::NON_FILL_POLYGON_MODE,
WgpuFeature::PolygonModeLine => wgpu::Features::POLYGON_MODE_LINE,
WgpuFeature::TextureCompressionEtc2 => wgpu::Features::TEXTURE_COMPRESSION_ETC2,
WgpuFeature::TextureCompressionAstcLdr => wgpu::Features::TEXTURE_COMPRESSION_ASTC_LDR,
WgpuFeature::TextureAdapterSpecificFormatFeatures => {
@ -724,6 +719,8 @@ impl WgpuFrom<WgpuLimits> for wgpu::Limits {
max_vertex_buffers: val.max_vertex_buffers,
max_vertex_attributes: val.max_vertex_attributes,
max_vertex_buffer_array_stride: val.max_vertex_buffer_array_stride,
min_storage_buffer_offset_alignment: val.min_storage_buffer_offset_alignment,
min_uniform_buffer_offset_alignment: val.min_uniform_buffer_offset_alignment,
}
}
}

View file

@ -13,7 +13,7 @@ use bevy::{
},
texture::{
Extent3d, SamplerDescriptor, TextureDescriptor, TextureDimension, TextureFormat,
TextureUsage,
TextureUsages,
},
},
window::WindowId,
@ -65,7 +65,7 @@ fn add_render_to_texture_graph(graph: &mut RenderGraph, size: Extent3d) {
sample_count: 1,
dimension: TextureDimension::D2,
format: Default::default(),
usage: TextureUsage::OUTPUT_ATTACHMENT | TextureUsage::SAMPLED,
usage: TextureUsages::OUTPUT_ATTACHMENT | TextureUsages::SAMPLED,
},
Some(SamplerDescriptor::default()),
Some(RENDER_TEXTURE_HANDLE),
@ -81,7 +81,7 @@ fn add_render_to_texture_graph(graph: &mut RenderGraph, size: Extent3d) {
sample_count: 1,
dimension: TextureDimension::D2,
format: TextureFormat::Depth32Float,
usage: TextureUsage::OUTPUT_ATTACHMENT | TextureUsage::SAMPLED,
usage: TextureUsages::OUTPUT_ATTACHMENT | TextureUsages::SAMPLED,
},
None,
None,

View file

@ -10,7 +10,7 @@ fn main() {
.insert_resource(WgpuOptions {
features: WgpuFeatures {
// The Wireframe requires NonFillPolygonMode feature
features: vec![WgpuFeature::NonFillPolygonMode],
features: vec![WgpuFeature::PolygonModeLine],
},
..Default::default()
})

View file

@ -57,7 +57,7 @@ impl RenderAsset for CustomMaterial {
let buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
contents: color.as_std140().as_bytes(),
label: None,
usage: BufferUsage::UNIFORM | BufferUsage::COPY_DST,
usage: BufferUsages::UNIFORM | BufferUsages::COPY_DST,
});
let bind_group = render_device.create_bind_group(&BindGroupDescriptor {
entries: &[BindGroupEntry {
@ -136,7 +136,7 @@ impl FromWorld for CustomPipeline {
let material_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
entries: &[BindGroupLayoutEntry {
binding: 0,
visibility: ShaderStage::FRAGMENT,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Buffer {
ty: BufferBindingType::Uniform,
has_dynamic_offset: false,
@ -163,7 +163,7 @@ impl FromWorld for CustomPipeline {
vertex: VertexState {
buffers: &[VertexBufferLayout {
array_stride: 32,
step_mode: InputStepMode::Vertex,
step_mode: VertexStepMode::Vertex,
attributes: &[
// Position (GOTCHA! Vertex_Position isn't first in the buffer due to how Mesh sorts attributes (alphabetically))
VertexAttribute {
@ -205,7 +205,7 @@ impl FromWorld for CustomPipeline {
operation: BlendOperation::Add,
},
}),
write_mask: ColorWrite::ALL,
write_mask: ColorWrites::ALL,
}],
}),
depth_stencil: Some(DepthStencilState {

View file

@ -7,7 +7,7 @@ use bevy::{
base::MainPass, CameraNode, PassNode, RenderGraph, WindowSwapChainNode,
WindowTextureNode,
},
texture::{Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsage},
texture::{Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages},
},
window::{CreateWindow, WindowDescriptor, WindowId},
};
@ -88,7 +88,7 @@ fn setup_pipeline(
window_id,
TextureDescriptor {
format: TextureFormat::Depth32Float,
usage: TextureUsage::OUTPUT_ATTACHMENT,
usage: TextureUsages::OUTPUT_ATTACHMENT,
sample_count: msaa.samples,
..Default::default()
},
@ -165,7 +165,7 @@ fn setup_pipeline(
sample_count: msaa.samples,
dimension: TextureDimension::D2,
format: TextureFormat::default(),
usage: TextureUsage::OUTPUT_ATTACHMENT,
usage: TextureUsages::OUTPUT_ATTACHMENT,
},
),
);

View file

@ -246,7 +246,7 @@ pub fn prepare_core_views_system(
dimension: TextureDimension::D2,
format: TextureFormat::Depth32Float, /* PERF: vulkan docs recommend using 24
* bit depth for better performance */
usage: TextureUsage::RENDER_ATTACHMENT,
usage: TextureUsages::RENDER_ATTACHMENT,
},
);
commands.entity(entity).insert(ViewDepthTexture {

View file

@ -22,7 +22,11 @@ impl Node for MainPassDriverNode {
if let Some(camera_2d) = extracted_cameras.entities.get(CameraPlugin::CAMERA_2D) {
let extracted_camera = world.entity(*camera_2d).get::<ExtractedCamera>().unwrap();
let extracted_window = extracted_windows.get(&extracted_camera.window_id).unwrap();
let swap_chain_texture = extracted_window.swap_chain_frame.as_ref().unwrap().clone();
let swap_chain_texture = extracted_window
.swap_chain_texture
.as_ref()
.unwrap()
.clone();
graph.run_sub_graph(
crate::draw_2d_graph::NAME,
vec![
@ -36,7 +40,11 @@ impl Node for MainPassDriverNode {
let extracted_camera = world.entity(*camera_3d).get::<ExtractedCamera>().unwrap();
let depth_texture = world.entity(*camera_3d).get::<ViewDepthTexture>().unwrap();
let extracted_window = extracted_windows.get(&extracted_camera.window_id).unwrap();
let swap_chain_texture = extracted_window.swap_chain_frame.as_ref().unwrap().clone();
let swap_chain_texture = extracted_window
.swap_chain_texture
.as_ref()
.unwrap()
.clone();
graph.run_sub_graph(
crate::draw_3d_graph::NAME,
vec![

View file

@ -32,4 +32,4 @@ thiserror = "1.0"
anyhow = "1.0.4"
base64 = "0.13.0"
percent-encoding = "2.1"
wgpu = "0.9"
wgpu = "0.11.0"

View file

@ -30,4 +30,4 @@ bitflags = "1.2"
# direct dependency required for derive macro
bytemuck = { version = "1", features = ["derive"] }
crevice = { path = "../../crates/crevice", version = "0.6.0" }
wgpu = "0.9"
wgpu = { version = "0.11.0", features = ["spirv"] }

View file

@ -6,7 +6,9 @@ use bevy_reflect::TypeUuid;
use bevy_render2::{
color::Color,
render_asset::{PrepareAssetError, RenderAsset, RenderAssetPlugin, RenderAssets},
render_resource::{BindGroup, Buffer, BufferInitDescriptor, BufferUsage, Sampler, TextureView},
render_resource::{
BindGroup, Buffer, BufferInitDescriptor, BufferUsages, Sampler, TextureView,
},
renderer::RenderDevice,
texture::Image,
};
@ -222,7 +224,7 @@ impl RenderAsset for StandardMaterial {
let buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
label: Some("pbr_standard_material_uniform_buffer"),
usage: BufferUsage::UNIFORM | BufferUsage::COPY_DST,
usage: BufferUsages::UNIFORM | BufferUsages::COPY_DST,
contents: value_std140.as_bytes(),
});
let bind_group = render_device.create_bind_group(&BindGroupDescriptor {

View file

@ -6,7 +6,7 @@ struct View {
world_position: vec3<f32>;
};
[[group(0), binding(0)]]
var view: View;
var<uniform> view: View;
[[block]]
@ -18,7 +18,7 @@ struct Mesh {
};
[[group(1), binding(0)]]
var mesh: Mesh;
var<uniform> mesh: Mesh;
struct Vertex {
[[location(0)]] position: vec3<f32>;

View file

@ -122,7 +122,7 @@ impl FromWorld for ShadowShaders {
// View
BindGroupLayoutEntry {
binding: 0,
visibility: ShaderStage::VERTEX | ShaderStage::FRAGMENT,
visibility: ShaderStages::VERTEX | ShaderStages::FRAGMENT,
ty: BindingType::Buffer {
ty: BufferBindingType::Uniform,
has_dynamic_offset: true,
@ -147,7 +147,7 @@ impl FromWorld for ShadowShaders {
vertex: VertexState {
buffers: &[VertexBufferLayout {
array_stride: 32,
step_mode: InputStepMode::Vertex,
step_mode: VertexStepMode::Vertex,
attributes: &[
// Position (GOTCHA! Vertex_Position isn't first in the buffer due to how Mesh sorts attributes (alphabetically))
VertexAttribute {
@ -411,8 +411,8 @@ pub fn prepare_lights(
sample_count: 1,
dimension: TextureDimension::D2,
format: SHADOW_FORMAT,
usage: TextureUsage::RENDER_ATTACHMENT | TextureUsage::SAMPLED,
label: Some("point_light_shadow_map_texture"),
usage: TextureUsages::RENDER_ATTACHMENT | TextureUsages::TEXTURE_BINDING,
},
);
let directional_light_depth_texture = texture_cache.get(
@ -427,8 +427,8 @@ pub fn prepare_lights(
sample_count: 1,
dimension: TextureDimension::D2,
format: SHADOW_FORMAT,
usage: TextureUsage::RENDER_ATTACHMENT | TextureUsage::SAMPLED,
label: Some("directional_light_shadow_map_texture"),
usage: TextureUsages::RENDER_ATTACHMENT | TextureUsages::TEXTURE_BINDING,
},
);
let mut view_lights = Vec::new();

View file

@ -136,7 +136,7 @@ impl FromWorld for PbrShaders {
// View
BindGroupLayoutEntry {
binding: 0,
visibility: ShaderStage::VERTEX | ShaderStage::FRAGMENT,
visibility: ShaderStages::VERTEX | ShaderStages::FRAGMENT,
ty: BindingType::Buffer {
ty: BufferBindingType::Uniform,
has_dynamic_offset: true,
@ -149,7 +149,7 @@ impl FromWorld for PbrShaders {
// Lights
BindGroupLayoutEntry {
binding: 1,
visibility: ShaderStage::FRAGMENT,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Buffer {
ty: BufferBindingType::Uniform,
has_dynamic_offset: true,
@ -162,7 +162,7 @@ impl FromWorld for PbrShaders {
// Point Shadow Texture Cube Array
BindGroupLayoutEntry {
binding: 2,
visibility: ShaderStage::FRAGMENT,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Texture {
multisampled: false,
sample_type: TextureSampleType::Depth,
@ -173,7 +173,7 @@ impl FromWorld for PbrShaders {
// Point Shadow Texture Array Sampler
BindGroupLayoutEntry {
binding: 3,
visibility: ShaderStage::FRAGMENT,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Sampler {
comparison: true,
filtering: true,
@ -183,7 +183,7 @@ impl FromWorld for PbrShaders {
// Directional Shadow Texture Array
BindGroupLayoutEntry {
binding: 4,
visibility: ShaderStage::FRAGMENT,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Texture {
multisampled: false,
sample_type: TextureSampleType::Depth,
@ -194,7 +194,7 @@ impl FromWorld for PbrShaders {
// Directional Shadow Texture Array Sampler
BindGroupLayoutEntry {
binding: 5,
visibility: ShaderStage::FRAGMENT,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Sampler {
comparison: true,
filtering: true,
@ -209,7 +209,7 @@ impl FromWorld for PbrShaders {
entries: &[
BindGroupLayoutEntry {
binding: 0,
visibility: ShaderStage::FRAGMENT,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Buffer {
ty: BufferBindingType::Uniform,
has_dynamic_offset: false,
@ -222,7 +222,7 @@ impl FromWorld for PbrShaders {
// Base Color Texture
BindGroupLayoutEntry {
binding: 1,
visibility: ShaderStage::FRAGMENT,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Texture {
multisampled: false,
sample_type: TextureSampleType::Float { filterable: true },
@ -233,7 +233,7 @@ impl FromWorld for PbrShaders {
// Base Color Texture Sampler
BindGroupLayoutEntry {
binding: 2,
visibility: ShaderStage::FRAGMENT,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Sampler {
comparison: false,
filtering: true,
@ -243,7 +243,7 @@ impl FromWorld for PbrShaders {
// Emissive Texture
BindGroupLayoutEntry {
binding: 3,
visibility: ShaderStage::FRAGMENT,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Texture {
multisampled: false,
sample_type: TextureSampleType::Float { filterable: true },
@ -254,7 +254,7 @@ impl FromWorld for PbrShaders {
// Emissive Texture Sampler
BindGroupLayoutEntry {
binding: 4,
visibility: ShaderStage::FRAGMENT,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Sampler {
comparison: false,
filtering: true,
@ -264,7 +264,7 @@ impl FromWorld for PbrShaders {
// Metallic Roughness Texture
BindGroupLayoutEntry {
binding: 5,
visibility: ShaderStage::FRAGMENT,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Texture {
multisampled: false,
sample_type: TextureSampleType::Float { filterable: true },
@ -275,7 +275,7 @@ impl FromWorld for PbrShaders {
// Metallic Roughness Texture Sampler
BindGroupLayoutEntry {
binding: 6,
visibility: ShaderStage::FRAGMENT,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Sampler {
comparison: false,
filtering: true,
@ -285,7 +285,7 @@ impl FromWorld for PbrShaders {
// Occlusion Texture
BindGroupLayoutEntry {
binding: 7,
visibility: ShaderStage::FRAGMENT,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Texture {
multisampled: false,
sample_type: TextureSampleType::Float { filterable: true },
@ -296,7 +296,7 @@ impl FromWorld for PbrShaders {
// Occlusion Texture Sampler
BindGroupLayoutEntry {
binding: 8,
visibility: ShaderStage::FRAGMENT,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Sampler {
comparison: false,
filtering: true,
@ -310,7 +310,7 @@ impl FromWorld for PbrShaders {
let mesh_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
entries: &[BindGroupLayoutEntry {
binding: 0,
visibility: ShaderStage::VERTEX | ShaderStage::FRAGMENT,
visibility: ShaderStages::VERTEX | ShaderStages::FRAGMENT,
ty: BindingType::Buffer {
ty: BufferBindingType::Uniform,
has_dynamic_offset: true,
@ -334,7 +334,7 @@ impl FromWorld for PbrShaders {
vertex: VertexState {
buffers: &[VertexBufferLayout {
array_stride: 32,
step_mode: InputStepMode::Vertex,
step_mode: VertexStepMode::Vertex,
attributes: &[
// Position (GOTCHA! Vertex_Position isn't first in the buffer due to how Mesh sorts attributes (alphabetically))
VertexAttribute {
@ -376,7 +376,7 @@ impl FromWorld for PbrShaders {
operation: BlendOperation::Add,
},
}),
write_mask: ColorWrite::ALL,
write_mask: ColorWrites::ALL,
}],
}),
depth_stencil: Some(DepthStencilState {
@ -426,6 +426,7 @@ impl FromWorld for PbrShaders {
texture: &texture,
mip_level: 0,
origin: Origin3d::ZERO,
aspect: wgpu::TextureAspect::All,
},
&image.data,
ImageDataLayout {

View file

@ -18,9 +18,9 @@ struct Mesh {
let MESH_FLAGS_SHADOW_RECEIVER_BIT: u32 = 1u;
[[group(0), binding(0)]]
var view: View;
var<uniform> view: View;
[[group(2), binding(0)]]
var mesh: Mesh;
var<uniform> mesh: Mesh;
struct Vertex {
[[location(0)]] position: vec3<f32>;
@ -136,7 +136,7 @@ struct Lights {
[[group(0), binding(1)]]
var lights: Lights;
var<uniform> lights: Lights;
[[group(0), binding(2)]]
var point_shadow_textures: texture_depth_cube_array;
[[group(0), binding(3)]]
@ -147,7 +147,7 @@ var directional_shadow_textures: texture_depth_2d_array;
var directional_shadow_textures_sampler: sampler_comparison;
[[group(1), binding(0)]]
var material: StandardMaterial;
var<uniform> material: StandardMaterial;
[[group(1), binding(1)]]
var base_color_texture: texture_2d<f32>;
[[group(1), binding(2)]]
@ -293,7 +293,7 @@ fn reinhard(color: vec3<f32>) -> vec3<f32> {
}
fn reinhard_extended(color: vec3<f32>, max_white: f32) -> vec3<f32> {
let numerator = color * (1.0f + (color / vec3<f32>(max_white * max_white)));
let numerator = color * (1.0 + (color / vec3<f32>(max_white * max_white)));
return numerator / (1.0 + color);
}
@ -310,14 +310,14 @@ fn change_luminance(c_in: vec3<f32>, l_out: f32) -> vec3<f32> {
fn reinhard_luminance(color: vec3<f32>) -> vec3<f32> {
let l_old = luminance(color);
let l_new = l_old / (1.0f + l_old);
let l_new = l_old / (1.0 + l_old);
return change_luminance(color, l_new);
}
fn reinhard_extended_luminance(color: vec3<f32>, max_white_l: f32) -> vec3<f32> {
let l_old = luminance(color);
let numerator = l_old * (1.0f + (l_old / (max_white_l * max_white_l)));
let l_new = numerator / (1.0f + l_old);
let numerator = l_old * (1.0 + (l_old / (max_white_l * max_white_l)));
let l_new = numerator / (1.0 + l_old);
return change_luminance(color, l_new);
}

View file

@ -29,8 +29,8 @@ bevy_utils = { path = "../../crates/bevy_utils", version = "0.5.0" }
image = { version = "0.23.12", default-features = false }
# misc
wgpu = "0.9"
naga = { version = "0.5", features = ["glsl-in", "spv-in", "spv-out", "wgsl-in", "wgsl-out"] }
wgpu = { version = "0.11.0", features = ["spirv"] }
naga = { version = "0.7.0", features = ["glsl-in", "spv-in", "spv-out", "wgsl-in", "wgsl-out"] }
serde = { version = "1", features = ["derive"] }
bitflags = "1.2.1"
smallvec = { version = "1.6", features = ["union", "const_generics"] }

View file

@ -25,7 +25,7 @@ use bevy_app::{App, AppLabel, Plugin};
use bevy_asset::AssetServer;
use bevy_ecs::prelude::*;
use std::ops::{Deref, DerefMut};
use wgpu::BackendBit;
use wgpu::Backends;
#[derive(Default)]
pub struct RenderPlugin;
@ -86,7 +86,7 @@ impl Plugin for RenderPlugin {
fn build(&self, app: &mut App) {
let (instance, device, queue) =
futures_lite::future::block_on(renderer::initialize_renderer(
BackendBit::PRIMARY,
wgpu::util::backend_bits_from_env().unwrap_or(Backends::PRIMARY),
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::HighPerformance,
..Default::default()

View file

@ -11,7 +11,9 @@ use bevy_math::*;
use bevy_reflect::TypeUuid;
use bevy_utils::EnumVariantMeta;
use std::{borrow::Cow, collections::BTreeMap};
use wgpu::{util::BufferInitDescriptor, BufferUsage, IndexFormat, PrimitiveTopology, VertexFormat};
use wgpu::{
util::BufferInitDescriptor, BufferUsages, IndexFormat, PrimitiveTopology, VertexFormat,
};
pub const INDEX_BUFFER_ASSET_INDEX: u64 = 0;
pub const VERTEX_ATTRIBUTE_BUFFER_ID: u64 = 10;
@ -553,14 +555,14 @@ impl RenderAsset for Mesh {
) -> Result<Self::PreparedAsset, PrepareAssetError<Self::ExtractedAsset>> {
let vertex_buffer_data = mesh.get_vertex_buffer_data();
let vertex_buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
usage: BufferUsage::VERTEX,
usage: BufferUsages::VERTEX,
label: None,
contents: &vertex_buffer_data,
});
let index_info = mesh.get_index_buffer_bytes().map(|data| GpuIndexInfo {
buffer: render_device.create_buffer_with_data(&BufferInitDescriptor {
usage: BufferUsage::INDEX,
usage: BufferUsages::INDEX,
contents: data,
label: None,
}),

View file

@ -3,14 +3,14 @@ use crate::{
renderer::{RenderDevice, RenderQueue},
};
use bevy_core::{cast_slice, Pod};
use wgpu::BufferUsage;
use wgpu::BufferUsages;
pub struct BufferVec<T: Pod> {
values: Vec<T>,
buffer: Option<Buffer>,
capacity: usize,
item_size: usize,
buffer_usage: BufferUsage,
buffer_usage: BufferUsages,
}
impl<T: Pod> Default for BufferVec<T> {
@ -19,14 +19,14 @@ impl<T: Pod> Default for BufferVec<T> {
values: Vec::new(),
buffer: None,
capacity: 0,
buffer_usage: BufferUsage::all(),
buffer_usage: BufferUsages::all(),
item_size: std::mem::size_of::<T>(),
}
}
}
impl<T: Pod> BufferVec<T> {
pub fn new(buffer_usage: BufferUsage) -> Self {
pub fn new(buffer_usage: BufferUsages) -> Self {
Self {
buffer_usage,
..Default::default()
@ -63,7 +63,7 @@ impl<T: Pod> BufferVec<T> {
self.buffer = Some(device.create_buffer(&wgpu::BufferDescriptor {
label: None,
size: size as wgpu::BufferAddress,
usage: BufferUsage::COPY_DST | self.buffer_usage,
usage: BufferUsages::COPY_DST | self.buffer_usage,
mapped_at_creation: false,
}));
}

View file

@ -17,14 +17,14 @@ pub use wgpu::{
util::BufferInitDescriptor, AddressMode, BindGroupDescriptor, BindGroupEntry, BindGroupLayout,
BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingResource, BindingType, BlendComponent,
BlendFactor, BlendOperation, BlendState, BufferAddress, BufferBindingType, BufferSize,
BufferUsage, ColorTargetState, ColorWrite, CompareFunction, ComputePassDescriptor,
BufferUsages, ColorTargetState, ColorWrites, CompareFunction, ComputePassDescriptor,
ComputePipelineDescriptor, DepthBiasState, DepthStencilState, Extent3d, Face, FilterMode,
FragmentState, FrontFace, IndexFormat, InputStepMode, LoadOp, MultisampleState, Operations,
PipelineLayout, PipelineLayoutDescriptor, PolygonMode, PrimitiveState, PrimitiveTopology,
FragmentState, FrontFace, IndexFormat, LoadOp, MultisampleState, Operations, PipelineLayout,
PipelineLayoutDescriptor, PolygonMode, PrimitiveState, PrimitiveTopology,
RenderPassColorAttachment, RenderPassDepthStencilAttachment, RenderPassDescriptor,
RenderPipelineDescriptor, SamplerDescriptor, ShaderFlags, ShaderModule, ShaderModuleDescriptor,
ShaderSource, ShaderStage, StencilFaceState, StencilOperation, StencilState,
RenderPipelineDescriptor, SamplerDescriptor, ShaderModule, ShaderModuleDescriptor,
ShaderSource, ShaderStages, StencilFaceState, StencilOperation, StencilState,
StorageTextureAccess, TextureAspect, TextureDescriptor, TextureDimension, TextureFormat,
TextureSampleType, TextureUsage, TextureViewDescriptor, TextureViewDimension, VertexAttribute,
VertexBufferLayout, VertexFormat, VertexState,
TextureSampleType, TextureUsages, TextureViewDescriptor, TextureViewDimension, VertexAttribute,
VertexBufferLayout, VertexFormat, VertexState, VertexStepMode,
};

View file

@ -45,7 +45,12 @@ pub struct TextureViewId(Uuid);
#[derive(Clone, Debug)]
pub enum TextureViewValue {
TextureView(Arc<wgpu::TextureView>),
SwapChainFrame(Arc<wgpu::SwapChainFrame>),
SurfaceTexture {
// NOTE: The order of these fields is important because the view must be dropped before the
// frame is dropped
view: Arc<wgpu::TextureView>,
texture: Arc<wgpu::SurfaceTexture>,
},
}
#[derive(Clone, Debug)]
@ -59,6 +64,14 @@ impl TextureView {
pub fn id(&self) -> TextureViewId {
self.id
}
#[inline]
pub fn take_surface_texture(self) -> Option<wgpu::SurfaceTexture> {
match self.value {
TextureViewValue::TextureView(_) => None,
TextureViewValue::SurfaceTexture { texture, .. } => Arc::try_unwrap(texture).ok(),
}
}
}
impl From<wgpu::TextureView> for TextureView {
@ -70,11 +83,14 @@ impl From<wgpu::TextureView> for TextureView {
}
}
impl From<wgpu::SwapChainFrame> for TextureView {
fn from(value: wgpu::SwapChainFrame) -> Self {
impl From<wgpu::SurfaceTexture> for TextureView {
fn from(value: wgpu::SurfaceTexture) -> Self {
let texture = Arc::new(value);
let view = Arc::new(texture.texture.create_view(&Default::default()));
TextureView {
id: TextureViewId(Uuid::new_v4()),
value: TextureViewValue::SwapChainFrame(Arc::new(value)),
value: TextureViewValue::SurfaceTexture { texture, view },
}
}
}
@ -86,7 +102,7 @@ impl Deref for TextureView {
fn deref(&self) -> &Self::Target {
match &self.value {
TextureViewValue::TextureView(value) => value,
TextureViewValue::SwapChainFrame(value) => &value.output.view,
TextureViewValue::SurfaceTexture { view, .. } => view,
}
}
}

View file

@ -4,7 +4,7 @@ use crate::{
};
use crevice::std140::{self, AsStd140, DynamicUniform, Std140};
use std::num::NonZeroU64;
use wgpu::{BindingResource, BufferBinding, BufferDescriptor, BufferUsage};
use wgpu::{BindingResource, BufferBinding, BufferDescriptor, BufferUsages};
pub struct UniformVec<T: AsStd140> {
values: Vec<T>,
@ -78,7 +78,7 @@ impl<T: AsStd140> UniformVec<T> {
self.uniform_buffer = Some(device.create_buffer(&BufferDescriptor {
label: None,
size: size as wgpu::BufferAddress,
usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
usage: BufferUsages::COPY_DST | BufferUsages::UNIFORM,
mapped_at_creation: false,
}));
}

View file

@ -1,14 +1,14 @@
mod graph_runner;
mod render_device;
use bevy_utils::tracing::info;
use bevy_utils::tracing::{info, info_span};
pub use graph_runner::*;
pub use render_device::*;
use crate::render_graph::RenderGraph;
use crate::{render_graph::RenderGraph, view::ExtractedWindows};
use bevy_ecs::prelude::*;
use std::sync::Arc;
use wgpu::{BackendBit, CommandEncoder, DeviceDescriptor, Instance, Queue, RequestAdapterOptions};
use wgpu::{Backends, CommandEncoder, DeviceDescriptor, Instance, Queue, RequestAdapterOptions};
pub fn render_system(world: &mut World) {
world.resource_scope(|world, mut graph: Mut<RenderGraph>| {
@ -24,13 +24,25 @@ pub fn render_system(world: &mut World) {
world,
)
.unwrap();
{
let span = info_span!("present_frames");
let _guard = span.enter();
let mut windows = world.get_resource_mut::<ExtractedWindows>().unwrap();
for window in windows.values_mut() {
if let Some(texture_view) = window.swap_chain_texture.take() {
if let Some(surface_texture) = texture_view.take_surface_texture() {
surface_texture.present();
}
}
}
}
}
pub type RenderQueue = Arc<Queue>;
pub type RenderInstance = Instance;
pub async fn initialize_renderer(
backends: BackendBit,
backends: Backends,
request_adapter_options: &RequestAdapterOptions<'_>,
device_descriptor: &DeviceDescriptor<'_>,
) -> (RenderInstance, RenderDevice, RenderQueue) {

View file

@ -145,12 +145,8 @@ impl RenderDevice {
///
/// - A old [`SwapChainFrame`] is still alive referencing an old swapchain.
/// - Texture format requested is unsupported on the swap chain.
pub fn create_swap_chain(
&self,
surface: &wgpu::Surface,
desc: &wgpu::SwapChainDescriptor,
) -> wgpu::SwapChain {
self.device.create_swap_chain(surface, desc)
pub fn configure_surface(&self, surface: &wgpu::Surface, config: &wgpu::SurfaceConfiguration) {
surface.configure(&self.device, config)
}
pub fn wgpu_device(&self) -> &wgpu::Device {

View file

@ -1,10 +1,10 @@
use bevy_asset::{AssetLoader, LoadContext, LoadedAsset};
use bevy_reflect::{TypeUuid, Uuid};
use bevy_utils::{tracing::error, BoxedFuture};
use naga::{valid::ModuleInfo, Module, ShaderStage};
use std::{borrow::Cow, collections::HashMap, marker::Copy};
use naga::{valid::ModuleInfo, Module};
use std::{borrow::Cow, marker::Copy};
use thiserror::Error;
use wgpu::{ShaderFlags, ShaderModuleDescriptor, ShaderSource};
use wgpu::{ShaderModuleDescriptor, ShaderSource};
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
pub struct ShaderId(Uuid);
@ -20,8 +20,8 @@ impl ShaderId {
pub enum ShaderReflectError {
#[error(transparent)]
WgslParse(#[from] naga::front::wgsl::ParseError),
#[error(transparent)]
GlslParse(#[from] naga::front::glsl::ParseError),
#[error("GLSL Parse Error: {0:?}")]
GlslParse(Vec<naga::front::glsl::Error>),
#[error(transparent)]
SpirVParse(#[from] naga::front::spv::Error),
#[error(transparent)]
@ -33,7 +33,7 @@ pub enum ShaderReflectError {
#[uuid = "d95bc916-6c55-4de3-9622-37e7b6969fda"]
pub enum Shader {
Wgsl(Cow<'static, str>),
Glsl(Cow<'static, str>),
Glsl(Cow<'static, str>, naga::ShaderStage),
SpirV(Vec<u8>),
// TODO: consider the following
// PrecompiledSpirVMacros(HashMap<HashSet<String>, Vec<u32>>)
@ -54,6 +54,7 @@ impl ShaderReflection {
flags: naga::back::spv::WriterFlags::empty(),
..naga::back::spv::Options::default()
},
None,
)
}
@ -67,17 +68,11 @@ impl Shader {
let module = match &self {
// TODO: process macros here
Shader::Wgsl(source) => naga::front::wgsl::parse_str(source)?,
Shader::Glsl(source) => {
let mut entry_points = HashMap::default();
entry_points.insert("vertex".to_string(), ShaderStage::Vertex);
entry_points.insert("fragment".to_string(), ShaderStage::Fragment);
naga::front::glsl::parse_str(
source,
&naga::front::glsl::Options {
entry_points,
defines: Default::default(),
},
)?
Shader::Glsl(source, shader_stage) => {
let mut parser = naga::front::glsl::Parser::default();
parser
.parse(&naga::front::glsl::Options::from(*shader_stage), source)
.map_err(ShaderReflectError::GlslParse)?
}
Shader::SpirV(source) => naga::front::spv::parse_u8_slice(
source,
@ -103,8 +98,8 @@ impl Shader {
Shader::Wgsl(source.into())
}
pub fn from_glsl(source: impl Into<Cow<'static, str>>) -> Shader {
Shader::Glsl(source.into())
pub fn from_glsl(source: impl Into<Cow<'static, str>>, stage: naga::ShaderStage) -> Shader {
Shader::Glsl(source.into(), stage)
}
pub fn from_spirv(source: Vec<u8>) -> Shader {
@ -143,11 +138,10 @@ impl AssetLoader for ShaderLoader {
impl<'a> From<&'a Shader> for ShaderModuleDescriptor<'a> {
fn from(shader: &'a Shader) -> Self {
ShaderModuleDescriptor {
flags: ShaderFlags::default(),
label: None,
source: match shader {
Shader::Wgsl(source) => ShaderSource::Wgsl(source.clone()),
Shader::Glsl(_source) => {
Shader::Glsl(_source, _stage) => {
let reflection = shader.reflect().unwrap();
let wgsl = reflection.get_wgsl().unwrap();
ShaderSource::Wgsl(wgsl.into())

View file

@ -42,7 +42,7 @@ impl Default for Image {
label: None,
mip_level_count: 1,
sample_count: 1,
usage: wgpu::TextureUsage::SAMPLED | wgpu::TextureUsage::COPY_DST,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
},
sampler_descriptor: wgpu::SamplerDescriptor::default(),
}
@ -369,6 +369,7 @@ impl RenderAsset for Image {
texture: &texture,
mip_level: 0,
origin: Origin3d::ZERO,
aspect: wgpu::TextureAspect::All,
},
&image.data,
ImageDataLayout {

View file

@ -6,7 +6,7 @@ use crate::{
};
use bevy_app::{App, Plugin};
use bevy_ecs::prelude::*;
use bevy_utils::{tracing::debug, HashMap};
use bevy_utils::{tracing::debug, HashMap, HashSet};
use bevy_window::{RawWindowHandleWrapper, WindowId, Windows};
use std::ops::{Deref, DerefMut};
use wgpu::TextureFormat;
@ -34,7 +34,7 @@ pub struct ExtractedWindow {
pub physical_width: u32,
pub physical_height: u32,
pub vsync: bool,
pub swap_chain_frame: Option<TextureView>,
pub swap_chain_texture: Option<TextureView>,
pub size_changed: bool,
}
@ -74,12 +74,12 @@ fn extract_windows(mut render_world: ResMut<RenderWorld>, windows: Res<Windows>)
physical_width: new_width,
physical_height: new_height,
vsync: window.vsync(),
swap_chain_frame: None,
swap_chain_texture: None,
size_changed: false,
});
// NOTE: Drop the swap chain frame here
extracted_window.swap_chain_frame = None;
extracted_window.swap_chain_texture = None;
extracted_window.size_changed = new_width != extracted_window.physical_width
|| new_height != extracted_window.physical_height;
@ -100,7 +100,8 @@ fn extract_windows(mut render_world: ResMut<RenderWorld>, windows: Res<Windows>)
#[derive(Default)]
pub struct WindowSurfaces {
surfaces: HashMap<WindowId, wgpu::Surface>,
swap_chains: HashMap<WindowId, wgpu::SwapChain>,
/// List of windows that we have already called the initial `configure_surface` for
configured_windows: HashSet<WindowId>,
}
pub fn prepare_windows(
@ -122,11 +123,11 @@ pub fn prepare_windows(
render_instance.create_surface(&window.handle.get_handle())
});
let swap_chain_descriptor = wgpu::SwapChainDescriptor {
let swap_chain_descriptor = wgpu::SurfaceConfiguration {
format: TextureFormat::bevy_default(),
width: window.physical_width,
height: window.physical_height,
usage: wgpu::TextureUsage::RENDER_ATTACHMENT,
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
present_mode: if window.vsync {
wgpu::PresentMode::Fifo
} else {
@ -134,34 +135,22 @@ pub fn prepare_windows(
},
};
if window.size_changed {
window_surfaces.swap_chains.insert(
window.id,
render_device.create_swap_chain(surface, &swap_chain_descriptor),
);
// Do the initial surface configuration if it hasn't been configured yet
if window_surfaces.configured_windows.insert(window.id) {
render_device.configure_surface(surface, &swap_chain_descriptor);
}
let swap_chain = window_surfaces
.swap_chains
.entry(window.id)
.or_insert_with(|| render_device.create_swap_chain(surface, &swap_chain_descriptor));
let frame = match swap_chain.get_current_frame() {
let frame = match surface.get_current_texture() {
Ok(swap_chain_frame) => swap_chain_frame,
Err(wgpu::SwapChainError::Outdated) => {
let new_swap_chain =
render_device.create_swap_chain(surface, &swap_chain_descriptor);
let frame = new_swap_chain
.get_current_frame()
.expect("Error recreating swap chain");
window_surfaces
.swap_chains
.insert(window.id, new_swap_chain);
frame
Err(wgpu::SurfaceError::Outdated) => {
render_device.configure_surface(surface, &swap_chain_descriptor);
surface
.get_current_texture()
.expect("Error reconfiguring surface")
}
err => err.expect("Failed to acquire next swap chain texture!"),
};
window.swap_chain_frame = Some(TextureView::from(frame));
window.swap_chain_texture = Some(TextureView::from(frame));
}
}

View file

@ -39,7 +39,7 @@ impl FromWorld for SpriteShaders {
let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
entries: &[BindGroupLayoutEntry {
binding: 0,
visibility: ShaderStage::VERTEX | ShaderStage::FRAGMENT,
visibility: ShaderStages::VERTEX | ShaderStages::FRAGMENT,
ty: BindingType::Buffer {
ty: BufferBindingType::Uniform,
has_dynamic_offset: true,
@ -56,7 +56,7 @@ impl FromWorld for SpriteShaders {
entries: &[
BindGroupLayoutEntry {
binding: 0,
visibility: ShaderStage::FRAGMENT,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Texture {
multisampled: false,
sample_type: TextureSampleType::Float { filterable: false },
@ -66,7 +66,7 @@ impl FromWorld for SpriteShaders {
},
BindGroupLayoutEntry {
binding: 1,
visibility: ShaderStage::FRAGMENT,
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Sampler {
comparison: false,
filtering: true,
@ -89,7 +89,7 @@ impl FromWorld for SpriteShaders {
vertex: VertexState {
buffers: &[VertexBufferLayout {
array_stride: 20,
step_mode: InputStepMode::Vertex,
step_mode: VertexStepMode::Vertex,
attributes: &[
VertexAttribute {
format: VertexFormat::Float32x3,
@ -123,7 +123,7 @@ impl FromWorld for SpriteShaders {
operation: BlendOperation::Add,
},
}),
write_mask: ColorWrite::ALL,
write_mask: ColorWrites::ALL,
}],
}),
layout: Some(&pipeline_layout),
@ -231,8 +231,8 @@ pub struct SpriteMeta {
impl Default for SpriteMeta {
fn default() -> Self {
Self {
vertices: BufferVec::new(BufferUsage::VERTEX),
indices: BufferVec::new(BufferUsage::INDEX),
vertices: BufferVec::new(BufferUsages::VERTEX),
indices: BufferVec::new(BufferUsages::INDEX),
view_bind_group: None,
quad: Quad {
size: Vec2::new(1.0, 1.0),

View file

@ -4,7 +4,7 @@ struct View {
world_position: vec3<f32>;
};
[[group(0), binding(0)]]
var view: View;
var<uniform> view: View;
struct VertexOutput {
[[location(0)]] uv: vec2<f32>;