mirror of
https://github.com/bevyengine/bevy
synced 2024-11-25 06:00:20 +00:00
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:
parent
40fccd29ca
commit
43e8a156fb
44 changed files with 286 additions and 267 deletions
|
@ -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"]
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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!"
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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()
|
||||
})
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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![
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"] }
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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"] }
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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,
|
||||
}),
|
||||
|
|
|
@ -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,
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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>;
|
||||
|
|
Loading…
Reference in a new issue