mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 04:33:37 +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"
|
license = "MIT OR Apache-2.0"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
repository = "https://github.com/bevyengine/bevy"
|
repository = "https://github.com/bevyengine/bevy"
|
||||||
|
resolver = "2"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
exclude = ["benches"]
|
exclude = ["benches"]
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
||||||
LoadOp, Operations, PassDescriptor, RenderPassColorAttachment,
|
LoadOp, Operations, PassDescriptor, RenderPassColorAttachment,
|
||||||
RenderPassDepthStencilAttachment, TextureAttachment,
|
RenderPassDepthStencilAttachment, TextureAttachment,
|
||||||
},
|
},
|
||||||
texture::{Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsage},
|
texture::{Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages},
|
||||||
Color,
|
Color,
|
||||||
};
|
};
|
||||||
use bevy_ecs::{reflect::ReflectComponent, world::World};
|
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,
|
dimension: TextureDimension::D2,
|
||||||
format: TextureFormat::Depth32Float, /* PERF: vulkan docs recommend using 24
|
format: TextureFormat::Depth32Float, /* PERF: vulkan docs recommend using 24
|
||||||
* bit depth for better performance */
|
* 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,
|
sample_count: msaa.samples,
|
||||||
dimension: TextureDimension::D2,
|
dimension: TextureDimension::D2,
|
||||||
format: TextureFormat::default(),
|
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();
|
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
|
if self
|
||||||
.window_created_event_reader
|
.window_created_event_reader
|
||||||
.iter(window_created_events)
|
.iter(window_created_events)
|
||||||
|
@ -62,10 +62,10 @@ impl Node for WindowSwapChainNode {
|
||||||
.iter(window_resized_events)
|
.iter(window_resized_events)
|
||||||
.any(|e| e.id == window.id())
|
.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(
|
output.set(
|
||||||
WINDOW_TEXTURE,
|
WINDOW_TEXTURE,
|
||||||
RenderResourceId::Texture(swap_chain_texture),
|
RenderResourceId::Texture(swap_chain_texture),
|
||||||
|
|
|
@ -31,15 +31,15 @@ impl HeadlessRenderResourceContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderResourceContext for 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()
|
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 {
|
fn create_sampler(&self, _sampler_descriptor: &SamplerDescriptor) -> SamplerId {
|
||||||
SamplerId::new()
|
SamplerId::new()
|
||||||
|
|
|
@ -12,10 +12,10 @@ use downcast_rs::{impl_downcast, Downcast};
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
pub trait RenderResourceContext: Downcast + Send + Sync + 'static {
|
pub trait RenderResourceContext: Downcast + Send + Sync + 'static {
|
||||||
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;
|
||||||
fn drop_swap_chain_texture(&self, resource: TextureId);
|
fn drop_surface_frame(&self, resource: TextureId);
|
||||||
fn drop_all_swap_chain_textures(&self);
|
fn drop_all_surface_frames(&self);
|
||||||
fn create_sampler(&self, sampler_descriptor: &SamplerDescriptor) -> SamplerId;
|
fn create_sampler(&self, sampler_descriptor: &SamplerDescriptor) -> SamplerId;
|
||||||
fn create_texture(&self, texture_descriptor: TextureDescriptor) -> TextureId;
|
fn create_texture(&self, texture_descriptor: TextureDescriptor) -> TextureId;
|
||||||
fn create_buffer(&self, buffer_info: BufferInfo) -> BufferId;
|
fn create_buffer(&self, buffer_info: BufferInfo) -> BufferId;
|
||||||
|
|
|
@ -106,9 +106,9 @@ pub fn glsl_to_spirv(
|
||||||
impl Into<shaderc::ShaderKind> for ShaderStage {
|
impl Into<shaderc::ShaderKind> for ShaderStage {
|
||||||
fn into(self) -> shaderc::ShaderKind {
|
fn into(self) -> shaderc::ShaderKind {
|
||||||
match self {
|
match self {
|
||||||
ShaderStage::Vertex => shaderc::ShaderKind::Vertex,
|
ShaderStages::VERTEX => shaderc::ShaderKind::Vertex,
|
||||||
ShaderStage::Fragment => shaderc::ShaderKind::Fragment,
|
ShaderStages::FRAGMENT => shaderc::ShaderKind::Fragment,
|
||||||
ShaderStage::Compute => shaderc::ShaderKind::Compute,
|
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
|
/// Describes a texture
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
|
@ -8,7 +8,7 @@ pub struct TextureDescriptor {
|
||||||
pub sample_count: u32,
|
pub sample_count: u32,
|
||||||
pub dimension: TextureDimension,
|
pub dimension: TextureDimension,
|
||||||
pub format: TextureFormat,
|
pub format: TextureFormat,
|
||||||
pub usage: TextureUsage,
|
pub usage: TextureUsages,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&Texture> for TextureDescriptor {
|
impl From<&Texture> for TextureDescriptor {
|
||||||
|
@ -19,7 +19,7 @@ impl From<&Texture> for TextureDescriptor {
|
||||||
sample_count: 1,
|
sample_count: 1,
|
||||||
dimension: texture.dimension,
|
dimension: texture.dimension,
|
||||||
format: texture.format,
|
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,
|
sample_count: 1,
|
||||||
dimension: TextureDimension::D2,
|
dimension: TextureDimension::D2,
|
||||||
format: TextureFormat::Rgba8UnormSrgb,
|
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! {
|
bitflags::bitflags! {
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct TextureUsage: u32 {
|
pub struct TextureUsages: u32 {
|
||||||
const COPY_SRC = 1;
|
const COPY_SRC = 1;
|
||||||
const COPY_DST = 2;
|
const COPY_DST = 2;
|
||||||
const SAMPLED = 4;
|
const SAMPLED = 4;
|
||||||
|
|
|
@ -21,7 +21,7 @@ struct Rect {
|
||||||
vec2 end;
|
vec2 end;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(set = 1, binding = 1) buffer TextureAtlas_textures {
|
layout(set = 1, binding = 1) readonly buffer TextureAtlas_textures {
|
||||||
Rect[] 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" }
|
bevy_utils = { path = "../bevy_utils", version = "0.5.0" }
|
||||||
|
|
||||||
# other
|
# other
|
||||||
wgpu = "0.9"
|
wgpu = { version = "0.11.0", features = ["spirv"] }
|
||||||
futures-lite = "1.4.0"
|
futures-lite = "1.4.0"
|
||||||
crossbeam-channel = "0.5.0"
|
crossbeam-channel = "0.5.0"
|
||||||
crossbeam-utils = "0.8.1"
|
crossbeam-utils = "0.8.1"
|
||||||
|
|
|
@ -29,9 +29,7 @@ impl WgpuResourceDiagnosticsPlugin {
|
||||||
DiagnosticId::from_u128(305855369913076220671125671543184691267);
|
DiagnosticId::from_u128(305855369913076220671125671543184691267);
|
||||||
pub const SHADER_MODULES: DiagnosticId =
|
pub const SHADER_MODULES: DiagnosticId =
|
||||||
DiagnosticId::from_u128(287681470908132753275843248383768232237);
|
DiagnosticId::from_u128(287681470908132753275843248383768232237);
|
||||||
pub const SWAP_CHAINS: DiagnosticId =
|
pub const SURFACE_FRAMES: DiagnosticId =
|
||||||
DiagnosticId::from_u128(199253035828743332241465305105689014605);
|
|
||||||
pub const SWAP_CHAIN_OUTPUTS: DiagnosticId =
|
|
||||||
DiagnosticId::from_u128(112048874168736161226721327099863374234);
|
DiagnosticId::from_u128(112048874168736161226721327099863374234);
|
||||||
pub const TEXTURES: DiagnosticId =
|
pub const TEXTURES: DiagnosticId =
|
||||||
DiagnosticId::from_u128(305955424195390184883220102469231911115);
|
DiagnosticId::from_u128(305955424195390184883220102469231911115);
|
||||||
|
@ -47,10 +45,8 @@ impl WgpuResourceDiagnosticsPlugin {
|
||||||
10,
|
10,
|
||||||
));
|
));
|
||||||
|
|
||||||
diagnostics.add(Diagnostic::new(Self::SWAP_CHAINS, "swap_chains", 10));
|
|
||||||
|
|
||||||
diagnostics.add(Diagnostic::new(
|
diagnostics.add(Diagnostic::new(
|
||||||
Self::SWAP_CHAIN_OUTPUTS,
|
Self::SURFACE_FRAMES,
|
||||||
"swap_chain_outputs",
|
"swap_chain_outputs",
|
||||||
10,
|
10,
|
||||||
));
|
));
|
||||||
|
@ -99,19 +95,10 @@ impl WgpuResourceDiagnosticsPlugin {
|
||||||
);
|
);
|
||||||
|
|
||||||
diagnostics.add_measurement(
|
diagnostics.add_measurement(
|
||||||
Self::SWAP_CHAINS,
|
Self::SURFACE_FRAMES,
|
||||||
render_resource_context
|
render_resource_context
|
||||||
.resources
|
.resources
|
||||||
.window_swap_chains
|
.surface_textures
|
||||||
.read()
|
|
||||||
.len() as f64,
|
|
||||||
);
|
|
||||||
|
|
||||||
diagnostics.add_measurement(
|
|
||||||
Self::SWAP_CHAIN_OUTPUTS,
|
|
||||||
render_resource_context
|
|
||||||
.resources
|
|
||||||
.swap_chain_frames
|
|
||||||
.read()
|
.read()
|
||||||
.len() as f64,
|
.len() as f64,
|
||||||
);
|
);
|
||||||
|
|
|
@ -29,15 +29,12 @@ pub enum WgpuFeature {
|
||||||
TimestampQuery,
|
TimestampQuery,
|
||||||
PipelineStatisticsQuery,
|
PipelineStatisticsQuery,
|
||||||
MappablePrimaryBuffers,
|
MappablePrimaryBuffers,
|
||||||
SampledTextureBindingArray,
|
|
||||||
SampledTextureArrayDynamicIndexing,
|
|
||||||
SampledTextureArrayNonUniformIndexing,
|
|
||||||
UnsizedBindingArray,
|
UnsizedBindingArray,
|
||||||
MultiDrawIndirect,
|
MultiDrawIndirect,
|
||||||
MultiDrawIndirectCount,
|
MultiDrawIndirectCount,
|
||||||
PushConstants,
|
PushConstants,
|
||||||
AddressModeClampToBorder,
|
AddressModeClampToBorder,
|
||||||
NonFillPolygonMode,
|
PolygonModeLine,
|
||||||
TextureCompressionEtc2,
|
TextureCompressionEtc2,
|
||||||
TextureCompressionAstcLdr,
|
TextureCompressionAstcLdr,
|
||||||
TextureAdapterSpecificFormatFeatures,
|
TextureAdapterSpecificFormatFeatures,
|
||||||
|
@ -70,6 +67,8 @@ pub struct WgpuLimits {
|
||||||
pub max_vertex_buffers: u32,
|
pub max_vertex_buffers: u32,
|
||||||
pub max_vertex_attributes: u32,
|
pub max_vertex_attributes: u32,
|
||||||
pub max_vertex_buffer_array_stride: 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 {
|
impl Default for WgpuLimits {
|
||||||
|
@ -96,6 +95,8 @@ impl Default for WgpuLimits {
|
||||||
max_vertex_buffers: default.max_vertex_buffers,
|
max_vertex_buffers: default.max_vertex_buffers,
|
||||||
max_vertex_attributes: default.max_vertex_attributes,
|
max_vertex_attributes: default.max_vertex_attributes,
|
||||||
max_vertex_buffer_array_stride: default.max_vertex_buffer_array_stride,
|
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);
|
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::Id(render_resource) => refs
|
||||||
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!"),
|
.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 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 COPY_BUFFER_ALIGNMENT: usize = wgpu::COPY_BUFFER_ALIGNMENT as usize;
|
||||||
pub const PUSH_CONSTANT_ALIGNMENT: u32 = wgpu::PUSH_CONSTANT_ALIGNMENT;
|
pub const PUSH_CONSTANT_ALIGNMENT: u32 = wgpu::PUSH_CONSTANT_ALIGNMENT;
|
||||||
|
|
||||||
|
@ -94,6 +95,7 @@ impl WgpuRenderResourceContext {
|
||||||
y: source_origin[1],
|
y: source_origin[1],
|
||||||
z: source_origin[2],
|
z: source_origin[2],
|
||||||
},
|
},
|
||||||
|
aspect: wgpu::TextureAspect::All,
|
||||||
},
|
},
|
||||||
wgpu::ImageCopyTexture {
|
wgpu::ImageCopyTexture {
|
||||||
texture: destination,
|
texture: destination,
|
||||||
|
@ -103,6 +105,7 @@ impl WgpuRenderResourceContext {
|
||||||
y: destination_origin[1],
|
y: destination_origin[1],
|
||||||
z: destination_origin[2],
|
z: destination_origin[2],
|
||||||
},
|
},
|
||||||
|
aspect: wgpu::TextureAspect::All,
|
||||||
},
|
},
|
||||||
size.wgpu_into(),
|
size.wgpu_into(),
|
||||||
)
|
)
|
||||||
|
@ -134,6 +137,7 @@ impl WgpuRenderResourceContext {
|
||||||
y: source_origin[1],
|
y: source_origin[1],
|
||||||
z: source_origin[2],
|
z: source_origin[2],
|
||||||
},
|
},
|
||||||
|
aspect: wgpu::TextureAspect::All,
|
||||||
},
|
},
|
||||||
wgpu::ImageCopyBuffer {
|
wgpu::ImageCopyBuffer {
|
||||||
buffer: destination,
|
buffer: destination,
|
||||||
|
@ -181,6 +185,7 @@ impl WgpuRenderResourceContext {
|
||||||
y: destination_origin[1],
|
y: destination_origin[1],
|
||||||
z: destination_origin[2],
|
z: destination_origin[2],
|
||||||
},
|
},
|
||||||
|
aspect: wgpu::TextureAspect::All,
|
||||||
},
|
},
|
||||||
size.wgpu_into(),
|
size.wgpu_into(),
|
||||||
);
|
);
|
||||||
|
@ -206,11 +211,11 @@ impl WgpuRenderResourceContext {
|
||||||
let shader_stage = if binding.shader_stage
|
let shader_stage = if binding.shader_stage
|
||||||
== BindingShaderStage::VERTEX | BindingShaderStage::FRAGMENT
|
== BindingShaderStage::VERTEX | BindingShaderStage::FRAGMENT
|
||||||
{
|
{
|
||||||
wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT
|
wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT
|
||||||
} else if binding.shader_stage == BindingShaderStage::VERTEX {
|
} else if binding.shader_stage == BindingShaderStage::VERTEX {
|
||||||
wgpu::ShaderStage::VERTEX
|
wgpu::ShaderStages::VERTEX
|
||||||
} else if binding.shader_stage == BindingShaderStage::FRAGMENT {
|
} else if binding.shader_stage == BindingShaderStage::FRAGMENT {
|
||||||
wgpu::ShaderStage::FRAGMENT
|
wgpu::ShaderStages::FRAGMENT
|
||||||
} else {
|
} else {
|
||||||
panic!("Invalid binding shader stage.")
|
panic!("Invalid binding shader stage.")
|
||||||
};
|
};
|
||||||
|
@ -230,14 +235,15 @@ impl WgpuRenderResourceContext {
|
||||||
bind_group_layouts.insert(descriptor.id, bind_group_layout);
|
bind_group_layouts.insert(descriptor.id, bind_group_layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_next_swap_chain_texture(&self, window_id: bevy_window::WindowId) -> Option<TextureId> {
|
fn try_next_surface_frame(&self, window_id: bevy_window::WindowId) -> Option<TextureId> {
|
||||||
let mut window_swap_chains = self.resources.window_swap_chains.write();
|
let mut window_surfaces = self.resources.window_surfaces.write();
|
||||||
let mut swap_chain_outputs = self.resources.swap_chain_frames.write();
|
let mut surface_frames = self.resources.surface_textures.write();
|
||||||
|
|
||||||
let window_swap_chain = window_swap_chains.get_mut(&window_id).unwrap();
|
let window_surface = window_surfaces.get_mut(&window_id).unwrap();
|
||||||
let next_texture = window_swap_chain.get_current_frame().ok()?;
|
let next_texture = window_surface.get_current_texture().ok()?;
|
||||||
|
let view = next_texture.texture.create_view(&Default::default());
|
||||||
let id = TextureId::new();
|
let id = TextureId::new();
|
||||||
swap_chain_outputs.insert(id, next_texture);
|
surface_frames.insert(id, (view, next_texture));
|
||||||
Some(id)
|
Some(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -339,7 +345,6 @@ impl RenderResourceContext for WgpuRenderResourceContext {
|
||||||
.create_shader_module(&wgpu::ShaderModuleDescriptor {
|
.create_shader_module(&wgpu::ShaderModuleDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
source: wgpu::ShaderSource::SpirV(spirv),
|
source: wgpu::ShaderSource::SpirV(spirv),
|
||||||
flags: Default::default(),
|
|
||||||
});
|
});
|
||||||
shader_modules.insert(shader_handle.clone_weak(), shader_module);
|
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);
|
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 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
|
let surface = surfaces
|
||||||
.get(&window.id())
|
.get(&window.id())
|
||||||
.expect("No surface found for window.");
|
.expect("No surface found for window.");
|
||||||
let swap_chain = self
|
surface.configure(&self.device, &surface_configuration);
|
||||||
.device
|
|
||||||
.create_swap_chain(surface, &swap_chain_descriptor);
|
|
||||||
|
|
||||||
window_swap_chains.insert(window.id(), swap_chain);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_swap_chain_texture(&self, window: &bevy_window::Window) -> TextureId {
|
fn next_surface_frame(&self, window: &bevy_window::Window) -> TextureId {
|
||||||
if let Some(texture_id) = self.try_next_swap_chain_texture(window.id()) {
|
if let Some(texture_id) = self.try_next_surface_frame(window.id()) {
|
||||||
texture_id
|
texture_id
|
||||||
} else {
|
} else {
|
||||||
self.resources
|
self.resources.window_surfaces.write().remove(&window.id());
|
||||||
.window_swap_chains
|
self.configure_surface(window);
|
||||||
.write()
|
self.try_next_surface_frame(window.id())
|
||||||
.remove(&window.id());
|
|
||||||
self.create_swap_chain(window);
|
|
||||||
self.try_next_swap_chain_texture(window.id())
|
|
||||||
.expect("Failed to acquire next swap chain texture!")
|
.expect("Failed to acquire next swap chain texture!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drop_swap_chain_texture(&self, texture: TextureId) {
|
fn drop_surface_frame(&self, texture: TextureId) {
|
||||||
let mut swap_chain_outputs = self.resources.swap_chain_frames.write();
|
let mut surface_frames = self.resources.surface_textures.write();
|
||||||
swap_chain_outputs.remove(&texture);
|
surface_frames.remove(&texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drop_all_swap_chain_textures(&self) {
|
fn drop_all_surface_frames(&self) {
|
||||||
let mut swap_chain_outputs = self.resources.swap_chain_frames.write();
|
let mut surface_frames = self.resources.surface_textures.write();
|
||||||
swap_chain_outputs.clear();
|
for (_, (_, texture)) in surface_frames.drain() {
|
||||||
|
texture.present();
|
||||||
|
}
|
||||||
|
|
||||||
|
surface_frames.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_asset_resource_untyped(
|
fn set_asset_resource_untyped(
|
||||||
|
|
|
@ -24,13 +24,13 @@ pub struct WgpuRenderer {
|
||||||
impl WgpuRenderer {
|
impl WgpuRenderer {
|
||||||
pub async fn new(options: WgpuOptions) -> Self {
|
pub async fn new(options: WgpuOptions) -> Self {
|
||||||
let backend = match options.backend {
|
let backend = match options.backend {
|
||||||
WgpuBackend::Auto => wgpu::BackendBit::PRIMARY,
|
WgpuBackend::Auto => wgpu::Backends::PRIMARY,
|
||||||
WgpuBackend::Vulkan => wgpu::BackendBit::VULKAN,
|
WgpuBackend::Vulkan => wgpu::Backends::VULKAN,
|
||||||
WgpuBackend::Metal => wgpu::BackendBit::METAL,
|
WgpuBackend::Metal => wgpu::Backends::METAL,
|
||||||
WgpuBackend::Dx12 => wgpu::BackendBit::DX12,
|
WgpuBackend::Dx12 => wgpu::Backends::DX12,
|
||||||
WgpuBackend::Dx11 => wgpu::BackendBit::DX11,
|
WgpuBackend::Dx11 => wgpu::Backends::DX11,
|
||||||
WgpuBackend::Gl => wgpu::BackendBit::GL,
|
WgpuBackend::Gl => wgpu::Backends::GL,
|
||||||
WgpuBackend::BrowserWgpu => wgpu::BackendBit::BROWSER_WEBGPU,
|
WgpuBackend::BrowserWgpu => wgpu::Backends::BROWSER_WEBGPU,
|
||||||
};
|
};
|
||||||
let instance = wgpu::Instance::new(backend);
|
let instance = wgpu::Instance::new(backend);
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ impl WgpuRenderer {
|
||||||
WgpuPowerOptions::LowPower => wgpu::PowerPreference::LowPower,
|
WgpuPowerOptions::LowPower => wgpu::PowerPreference::LowPower,
|
||||||
},
|
},
|
||||||
compatible_surface: None,
|
compatible_surface: None,
|
||||||
|
..Default::default()
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.expect("Unable to find a GPU! Make sure you have installed required drivers!");
|
.expect("Unable to find a GPU! Make sure you have installed required drivers!");
|
||||||
|
@ -56,12 +57,14 @@ impl WgpuRenderer {
|
||||||
#[cfg(not(feature = "trace"))]
|
#[cfg(not(feature = "trace"))]
|
||||||
let trace_path = None;
|
let trace_path = None;
|
||||||
|
|
||||||
|
let adapter_limits = adapter.limits();
|
||||||
|
|
||||||
let (device, queue) = adapter
|
let (device, queue) = adapter
|
||||||
.request_device(
|
.request_device(
|
||||||
&wgpu::DeviceDescriptor {
|
&wgpu::DeviceDescriptor {
|
||||||
label: options.device_label.as_ref().map(|a| a.as_ref()),
|
label: options.device_label.as_ref().map(|a| a.as_ref()),
|
||||||
features: options.features.wgpu_into(),
|
features: options.features.wgpu_into(),
|
||||||
limits: options.limits.wgpu_into(),
|
limits: adapter_limits,
|
||||||
},
|
},
|
||||||
trace_path,
|
trace_path,
|
||||||
)
|
)
|
||||||
|
@ -129,7 +132,7 @@ impl WgpuRenderer {
|
||||||
let render_resource_context = world
|
let render_resource_context = world
|
||||||
.get_resource::<Box<dyn RenderResourceContext>>()
|
.get_resource::<Box<dyn RenderResourceContext>>()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
render_resource_context.drop_all_swap_chain_textures();
|
render_resource_context.drop_all_surface_frames();
|
||||||
render_resource_context.remove_stale_bind_groups();
|
render_resource_context.remove_stale_bind_groups();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,8 @@ pub struct WgpuBindGroupInfo {
|
||||||
pub struct WgpuResourcesReadLock<'a> {
|
pub struct WgpuResourcesReadLock<'a> {
|
||||||
pub buffers: RwLockReadGuard<'a, HashMap<BufferId, Arc<wgpu::Buffer>>>,
|
pub buffers: RwLockReadGuard<'a, HashMap<BufferId, Arc<wgpu::Buffer>>>,
|
||||||
pub textures: RwLockReadGuard<'a, HashMap<TextureId, wgpu::TextureView>>,
|
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:
|
pub render_pipelines:
|
||||||
RwLockReadGuard<'a, HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>>,
|
RwLockReadGuard<'a, HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>>,
|
||||||
pub bind_groups: RwLockReadGuard<'a, HashMap<BindGroupDescriptorId, WgpuBindGroupInfo>>,
|
pub bind_groups: RwLockReadGuard<'a, HashMap<BindGroupDescriptorId, WgpuBindGroupInfo>>,
|
||||||
|
@ -59,7 +60,7 @@ impl<'a> WgpuResourcesReadLock<'a> {
|
||||||
WgpuResourceRefs {
|
WgpuResourceRefs {
|
||||||
buffers: &self.buffers,
|
buffers: &self.buffers,
|
||||||
textures: &self.textures,
|
textures: &self.textures,
|
||||||
swap_chain_frames: &self.swap_chain_frames,
|
surface_textures: &self.surface_textures,
|
||||||
render_pipelines: &self.render_pipelines,
|
render_pipelines: &self.render_pipelines,
|
||||||
bind_groups: &self.bind_groups,
|
bind_groups: &self.bind_groups,
|
||||||
used_bind_group_sender: &self.used_bind_group_sender,
|
used_bind_group_sender: &self.used_bind_group_sender,
|
||||||
|
@ -73,7 +74,7 @@ impl<'a> WgpuResourcesReadLock<'a> {
|
||||||
pub struct WgpuResourceRefs<'a> {
|
pub struct WgpuResourceRefs<'a> {
|
||||||
pub buffers: &'a HashMap<BufferId, Arc<wgpu::Buffer>>,
|
pub buffers: &'a HashMap<BufferId, Arc<wgpu::Buffer>>,
|
||||||
pub textures: &'a HashMap<TextureId, wgpu::TextureView>,
|
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 render_pipelines: &'a HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>,
|
||||||
pub bind_groups: &'a HashMap<BindGroupDescriptorId, WgpuBindGroupInfo>,
|
pub bind_groups: &'a HashMap<BindGroupDescriptorId, WgpuBindGroupInfo>,
|
||||||
pub used_bind_group_sender: &'a Sender<BindGroupId>,
|
pub used_bind_group_sender: &'a Sender<BindGroupId>,
|
||||||
|
@ -84,8 +85,8 @@ pub struct WgpuResources {
|
||||||
pub buffer_infos: Arc<RwLock<HashMap<BufferId, BufferInfo>>>,
|
pub buffer_infos: Arc<RwLock<HashMap<BufferId, BufferInfo>>>,
|
||||||
pub texture_descriptors: Arc<RwLock<HashMap<TextureId, TextureDescriptor>>>,
|
pub texture_descriptors: Arc<RwLock<HashMap<TextureId, TextureDescriptor>>>,
|
||||||
pub window_surfaces: Arc<RwLock<HashMap<WindowId, wgpu::Surface>>>,
|
pub window_surfaces: Arc<RwLock<HashMap<WindowId, wgpu::Surface>>>,
|
||||||
pub window_swap_chains: Arc<RwLock<HashMap<WindowId, wgpu::SwapChain>>>,
|
pub surface_textures:
|
||||||
pub swap_chain_frames: Arc<RwLock<HashMap<TextureId, wgpu::SwapChainFrame>>>,
|
Arc<RwLock<HashMap<TextureId, (wgpu::TextureView, wgpu::SurfaceTexture)>>>,
|
||||||
pub buffers: Arc<RwLock<HashMap<BufferId, Arc<wgpu::Buffer>>>>,
|
pub buffers: Arc<RwLock<HashMap<BufferId, Arc<wgpu::Buffer>>>>,
|
||||||
pub texture_views: Arc<RwLock<HashMap<TextureId, wgpu::TextureView>>>,
|
pub texture_views: Arc<RwLock<HashMap<TextureId, wgpu::TextureView>>>,
|
||||||
pub textures: Arc<RwLock<HashMap<TextureId, wgpu::Texture>>>,
|
pub textures: Arc<RwLock<HashMap<TextureId, wgpu::Texture>>>,
|
||||||
|
@ -103,7 +104,7 @@ impl WgpuResources {
|
||||||
WgpuResourcesReadLock {
|
WgpuResourcesReadLock {
|
||||||
buffers: self.buffers.read(),
|
buffers: self.buffers.read(),
|
||||||
textures: self.texture_views.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(),
|
render_pipelines: self.render_pipelines.read(),
|
||||||
bind_groups: self.bind_groups.read(),
|
bind_groups: self.bind_groups.read(),
|
||||||
used_bind_group_sender: self.bind_group_counter.used_bind_group_sender.clone(),
|
used_bind_group_sender: self.bind_group_counter.used_bind_group_sender.clone(),
|
||||||
|
|
|
@ -13,7 +13,7 @@ use bevy_render::{
|
||||||
texture::{
|
texture::{
|
||||||
AddressMode, Extent3d, FilterMode, SamplerBorderColor, SamplerDescriptor,
|
AddressMode, Extent3d, FilterMode, SamplerBorderColor, SamplerDescriptor,
|
||||||
StorageTextureAccess, TextureDescriptor, TextureDimension, TextureFormat,
|
StorageTextureAccess, TextureDescriptor, TextureDimension, TextureFormat,
|
||||||
TextureSampleType, TextureUsage, TextureViewDimension,
|
TextureSampleType, TextureUsages, TextureViewDimension,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use bevy_window::Window;
|
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 {
|
fn from(val: InputStepMode) -> Self {
|
||||||
match val {
|
match val {
|
||||||
InputStepMode::Vertex => wgpu::InputStepMode::Vertex,
|
InputStepMode::Vertex => wgpu::VertexStepMode::Vertex,
|
||||||
InputStepMode::Instance => wgpu::InputStepMode::Instance,
|
InputStepMode::Instance => wgpu::VertexStepMode::Instance,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ impl WgpuFrom<InputStepMode> for wgpu::InputStepMode {
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct OwnedWgpuVertexBufferLayout {
|
pub struct OwnedWgpuVertexBufferLayout {
|
||||||
pub array_stride: wgpu::BufferAddress,
|
pub array_stride: wgpu::BufferAddress,
|
||||||
pub step_mode: wgpu::InputStepMode,
|
pub step_mode: wgpu::VertexStepMode,
|
||||||
pub attributes: Vec<wgpu::VertexAttribute>,
|
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 {
|
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 {
|
} => wgpu::BindingType::Buffer {
|
||||||
ty: BufferBindingType::Uniform,
|
ty: BufferBindingType::Uniform,
|
||||||
has_dynamic_offset: *has_dynamic_offset,
|
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 {
|
BindType::StorageBuffer {
|
||||||
has_dynamic_offset,
|
has_dynamic_offset,
|
||||||
|
@ -200,7 +202,9 @@ impl WgpuFrom<&BindType> for wgpu::BindingType {
|
||||||
read_only: *readonly,
|
read_only: *readonly,
|
||||||
},
|
},
|
||||||
has_dynamic_offset: *has_dynamic_offset,
|
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 {
|
BindType::Texture {
|
||||||
view_dimension,
|
view_dimension,
|
||||||
|
@ -346,9 +350,9 @@ impl WgpuFrom<TextureFormat> for wgpu::TextureFormat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WgpuFrom<TextureUsage> for wgpu::TextureUsage {
|
impl WgpuFrom<TextureUsages> for wgpu::TextureUsages {
|
||||||
fn from(val: TextureUsage) -> Self {
|
fn from(val: TextureUsages) -> Self {
|
||||||
wgpu::TextureUsage::from_bits(val.bits()).unwrap()
|
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 {
|
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 {
|
fn from(window: &Window) -> Self {
|
||||||
wgpu::SwapChainDescriptor {
|
wgpu::SurfaceConfiguration {
|
||||||
usage: wgpu::TextureUsage::RENDER_ATTACHMENT,
|
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
|
||||||
format: TextureFormat::default().wgpu_into(),
|
format: TextureFormat::default().wgpu_into(),
|
||||||
width: window.physical_width().max(1),
|
width: window.physical_width().max(1),
|
||||||
height: window.physical_height().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::TimestampQuery => wgpu::Features::TIMESTAMP_QUERY,
|
||||||
WgpuFeature::PipelineStatisticsQuery => wgpu::Features::PIPELINE_STATISTICS_QUERY,
|
WgpuFeature::PipelineStatisticsQuery => wgpu::Features::PIPELINE_STATISTICS_QUERY,
|
||||||
WgpuFeature::MappablePrimaryBuffers => wgpu::Features::MAPPABLE_PRIMARY_BUFFERS,
|
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::UnsizedBindingArray => wgpu::Features::UNSIZED_BINDING_ARRAY,
|
||||||
WgpuFeature::MultiDrawIndirect => wgpu::Features::MULTI_DRAW_INDIRECT,
|
WgpuFeature::MultiDrawIndirect => wgpu::Features::MULTI_DRAW_INDIRECT,
|
||||||
WgpuFeature::MultiDrawIndirectCount => wgpu::Features::MULTI_DRAW_INDIRECT_COUNT,
|
WgpuFeature::MultiDrawIndirectCount => wgpu::Features::MULTI_DRAW_INDIRECT_COUNT,
|
||||||
WgpuFeature::PushConstants => wgpu::Features::PUSH_CONSTANTS,
|
WgpuFeature::PushConstants => wgpu::Features::PUSH_CONSTANTS,
|
||||||
WgpuFeature::AddressModeClampToBorder => wgpu::Features::ADDRESS_MODE_CLAMP_TO_BORDER,
|
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::TextureCompressionEtc2 => wgpu::Features::TEXTURE_COMPRESSION_ETC2,
|
||||||
WgpuFeature::TextureCompressionAstcLdr => wgpu::Features::TEXTURE_COMPRESSION_ASTC_LDR,
|
WgpuFeature::TextureCompressionAstcLdr => wgpu::Features::TEXTURE_COMPRESSION_ASTC_LDR,
|
||||||
WgpuFeature::TextureAdapterSpecificFormatFeatures => {
|
WgpuFeature::TextureAdapterSpecificFormatFeatures => {
|
||||||
|
@ -724,6 +719,8 @@ impl WgpuFrom<WgpuLimits> for wgpu::Limits {
|
||||||
max_vertex_buffers: val.max_vertex_buffers,
|
max_vertex_buffers: val.max_vertex_buffers,
|
||||||
max_vertex_attributes: val.max_vertex_attributes,
|
max_vertex_attributes: val.max_vertex_attributes,
|
||||||
max_vertex_buffer_array_stride: val.max_vertex_buffer_array_stride,
|
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::{
|
texture::{
|
||||||
Extent3d, SamplerDescriptor, TextureDescriptor, TextureDimension, TextureFormat,
|
Extent3d, SamplerDescriptor, TextureDescriptor, TextureDimension, TextureFormat,
|
||||||
TextureUsage,
|
TextureUsages,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
window::WindowId,
|
window::WindowId,
|
||||||
|
@ -65,7 +65,7 @@ fn add_render_to_texture_graph(graph: &mut RenderGraph, size: Extent3d) {
|
||||||
sample_count: 1,
|
sample_count: 1,
|
||||||
dimension: TextureDimension::D2,
|
dimension: TextureDimension::D2,
|
||||||
format: Default::default(),
|
format: Default::default(),
|
||||||
usage: TextureUsage::OUTPUT_ATTACHMENT | TextureUsage::SAMPLED,
|
usage: TextureUsages::OUTPUT_ATTACHMENT | TextureUsages::SAMPLED,
|
||||||
},
|
},
|
||||||
Some(SamplerDescriptor::default()),
|
Some(SamplerDescriptor::default()),
|
||||||
Some(RENDER_TEXTURE_HANDLE),
|
Some(RENDER_TEXTURE_HANDLE),
|
||||||
|
@ -81,7 +81,7 @@ fn add_render_to_texture_graph(graph: &mut RenderGraph, size: Extent3d) {
|
||||||
sample_count: 1,
|
sample_count: 1,
|
||||||
dimension: TextureDimension::D2,
|
dimension: TextureDimension::D2,
|
||||||
format: TextureFormat::Depth32Float,
|
format: TextureFormat::Depth32Float,
|
||||||
usage: TextureUsage::OUTPUT_ATTACHMENT | TextureUsage::SAMPLED,
|
usage: TextureUsages::OUTPUT_ATTACHMENT | TextureUsages::SAMPLED,
|
||||||
},
|
},
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
|
|
|
@ -10,7 +10,7 @@ fn main() {
|
||||||
.insert_resource(WgpuOptions {
|
.insert_resource(WgpuOptions {
|
||||||
features: WgpuFeatures {
|
features: WgpuFeatures {
|
||||||
// The Wireframe requires NonFillPolygonMode feature
|
// The Wireframe requires NonFillPolygonMode feature
|
||||||
features: vec![WgpuFeature::NonFillPolygonMode],
|
features: vec![WgpuFeature::PolygonModeLine],
|
||||||
},
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
|
|
@ -57,7 +57,7 @@ impl RenderAsset for CustomMaterial {
|
||||||
let buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
|
let buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
|
||||||
contents: color.as_std140().as_bytes(),
|
contents: color.as_std140().as_bytes(),
|
||||||
label: None,
|
label: None,
|
||||||
usage: BufferUsage::UNIFORM | BufferUsage::COPY_DST,
|
usage: BufferUsages::UNIFORM | BufferUsages::COPY_DST,
|
||||||
});
|
});
|
||||||
let bind_group = render_device.create_bind_group(&BindGroupDescriptor {
|
let bind_group = render_device.create_bind_group(&BindGroupDescriptor {
|
||||||
entries: &[BindGroupEntry {
|
entries: &[BindGroupEntry {
|
||||||
|
@ -136,7 +136,7 @@ impl FromWorld for CustomPipeline {
|
||||||
let material_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
|
let material_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
|
||||||
entries: &[BindGroupLayoutEntry {
|
entries: &[BindGroupLayoutEntry {
|
||||||
binding: 0,
|
binding: 0,
|
||||||
visibility: ShaderStage::FRAGMENT,
|
visibility: ShaderStages::FRAGMENT,
|
||||||
ty: BindingType::Buffer {
|
ty: BindingType::Buffer {
|
||||||
ty: BufferBindingType::Uniform,
|
ty: BufferBindingType::Uniform,
|
||||||
has_dynamic_offset: false,
|
has_dynamic_offset: false,
|
||||||
|
@ -163,7 +163,7 @@ impl FromWorld for CustomPipeline {
|
||||||
vertex: VertexState {
|
vertex: VertexState {
|
||||||
buffers: &[VertexBufferLayout {
|
buffers: &[VertexBufferLayout {
|
||||||
array_stride: 32,
|
array_stride: 32,
|
||||||
step_mode: InputStepMode::Vertex,
|
step_mode: VertexStepMode::Vertex,
|
||||||
attributes: &[
|
attributes: &[
|
||||||
// Position (GOTCHA! Vertex_Position isn't first in the buffer due to how Mesh sorts attributes (alphabetically))
|
// Position (GOTCHA! Vertex_Position isn't first in the buffer due to how Mesh sorts attributes (alphabetically))
|
||||||
VertexAttribute {
|
VertexAttribute {
|
||||||
|
@ -205,7 +205,7 @@ impl FromWorld for CustomPipeline {
|
||||||
operation: BlendOperation::Add,
|
operation: BlendOperation::Add,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
write_mask: ColorWrite::ALL,
|
write_mask: ColorWrites::ALL,
|
||||||
}],
|
}],
|
||||||
}),
|
}),
|
||||||
depth_stencil: Some(DepthStencilState {
|
depth_stencil: Some(DepthStencilState {
|
||||||
|
|
|
@ -7,7 +7,7 @@ use bevy::{
|
||||||
base::MainPass, CameraNode, PassNode, RenderGraph, WindowSwapChainNode,
|
base::MainPass, CameraNode, PassNode, RenderGraph, WindowSwapChainNode,
|
||||||
WindowTextureNode,
|
WindowTextureNode,
|
||||||
},
|
},
|
||||||
texture::{Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsage},
|
texture::{Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages},
|
||||||
},
|
},
|
||||||
window::{CreateWindow, WindowDescriptor, WindowId},
|
window::{CreateWindow, WindowDescriptor, WindowId},
|
||||||
};
|
};
|
||||||
|
@ -88,7 +88,7 @@ fn setup_pipeline(
|
||||||
window_id,
|
window_id,
|
||||||
TextureDescriptor {
|
TextureDescriptor {
|
||||||
format: TextureFormat::Depth32Float,
|
format: TextureFormat::Depth32Float,
|
||||||
usage: TextureUsage::OUTPUT_ATTACHMENT,
|
usage: TextureUsages::OUTPUT_ATTACHMENT,
|
||||||
sample_count: msaa.samples,
|
sample_count: msaa.samples,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
@ -165,7 +165,7 @@ fn setup_pipeline(
|
||||||
sample_count: msaa.samples,
|
sample_count: msaa.samples,
|
||||||
dimension: TextureDimension::D2,
|
dimension: TextureDimension::D2,
|
||||||
format: TextureFormat::default(),
|
format: TextureFormat::default(),
|
||||||
usage: TextureUsage::OUTPUT_ATTACHMENT,
|
usage: TextureUsages::OUTPUT_ATTACHMENT,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -246,7 +246,7 @@ pub fn prepare_core_views_system(
|
||||||
dimension: TextureDimension::D2,
|
dimension: TextureDimension::D2,
|
||||||
format: TextureFormat::Depth32Float, /* PERF: vulkan docs recommend using 24
|
format: TextureFormat::Depth32Float, /* PERF: vulkan docs recommend using 24
|
||||||
* bit depth for better performance */
|
* bit depth for better performance */
|
||||||
usage: TextureUsage::RENDER_ATTACHMENT,
|
usage: TextureUsages::RENDER_ATTACHMENT,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
commands.entity(entity).insert(ViewDepthTexture {
|
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) {
|
if let Some(camera_2d) = extracted_cameras.entities.get(CameraPlugin::CAMERA_2D) {
|
||||||
let extracted_camera = world.entity(*camera_2d).get::<ExtractedCamera>().unwrap();
|
let extracted_camera = world.entity(*camera_2d).get::<ExtractedCamera>().unwrap();
|
||||||
let extracted_window = extracted_windows.get(&extracted_camera.window_id).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(
|
graph.run_sub_graph(
|
||||||
crate::draw_2d_graph::NAME,
|
crate::draw_2d_graph::NAME,
|
||||||
vec![
|
vec![
|
||||||
|
@ -36,7 +40,11 @@ impl Node for MainPassDriverNode {
|
||||||
let extracted_camera = world.entity(*camera_3d).get::<ExtractedCamera>().unwrap();
|
let extracted_camera = world.entity(*camera_3d).get::<ExtractedCamera>().unwrap();
|
||||||
let depth_texture = world.entity(*camera_3d).get::<ViewDepthTexture>().unwrap();
|
let depth_texture = world.entity(*camera_3d).get::<ViewDepthTexture>().unwrap();
|
||||||
let extracted_window = extracted_windows.get(&extracted_camera.window_id).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(
|
graph.run_sub_graph(
|
||||||
crate::draw_3d_graph::NAME,
|
crate::draw_3d_graph::NAME,
|
||||||
vec![
|
vec![
|
||||||
|
|
|
@ -32,4 +32,4 @@ thiserror = "1.0"
|
||||||
anyhow = "1.0.4"
|
anyhow = "1.0.4"
|
||||||
base64 = "0.13.0"
|
base64 = "0.13.0"
|
||||||
percent-encoding = "2.1"
|
percent-encoding = "2.1"
|
||||||
wgpu = "0.9"
|
wgpu = "0.11.0"
|
||||||
|
|
|
@ -30,4 +30,4 @@ bitflags = "1.2"
|
||||||
# direct dependency required for derive macro
|
# direct dependency required for derive macro
|
||||||
bytemuck = { version = "1", features = ["derive"] }
|
bytemuck = { version = "1", features = ["derive"] }
|
||||||
crevice = { path = "../../crates/crevice", version = "0.6.0" }
|
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::{
|
use bevy_render2::{
|
||||||
color::Color,
|
color::Color,
|
||||||
render_asset::{PrepareAssetError, RenderAsset, RenderAssetPlugin, RenderAssets},
|
render_asset::{PrepareAssetError, RenderAsset, RenderAssetPlugin, RenderAssets},
|
||||||
render_resource::{BindGroup, Buffer, BufferInitDescriptor, BufferUsage, Sampler, TextureView},
|
render_resource::{
|
||||||
|
BindGroup, Buffer, BufferInitDescriptor, BufferUsages, Sampler, TextureView,
|
||||||
|
},
|
||||||
renderer::RenderDevice,
|
renderer::RenderDevice,
|
||||||
texture::Image,
|
texture::Image,
|
||||||
};
|
};
|
||||||
|
@ -222,7 +224,7 @@ impl RenderAsset for StandardMaterial {
|
||||||
|
|
||||||
let buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
|
let buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
|
||||||
label: Some("pbr_standard_material_uniform_buffer"),
|
label: Some("pbr_standard_material_uniform_buffer"),
|
||||||
usage: BufferUsage::UNIFORM | BufferUsage::COPY_DST,
|
usage: BufferUsages::UNIFORM | BufferUsages::COPY_DST,
|
||||||
contents: value_std140.as_bytes(),
|
contents: value_std140.as_bytes(),
|
||||||
});
|
});
|
||||||
let bind_group = render_device.create_bind_group(&BindGroupDescriptor {
|
let bind_group = render_device.create_bind_group(&BindGroupDescriptor {
|
||||||
|
|
|
@ -6,7 +6,7 @@ struct View {
|
||||||
world_position: vec3<f32>;
|
world_position: vec3<f32>;
|
||||||
};
|
};
|
||||||
[[group(0), binding(0)]]
|
[[group(0), binding(0)]]
|
||||||
var view: View;
|
var<uniform> view: View;
|
||||||
|
|
||||||
|
|
||||||
[[block]]
|
[[block]]
|
||||||
|
@ -18,7 +18,7 @@ struct Mesh {
|
||||||
};
|
};
|
||||||
|
|
||||||
[[group(1), binding(0)]]
|
[[group(1), binding(0)]]
|
||||||
var mesh: Mesh;
|
var<uniform> mesh: Mesh;
|
||||||
|
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
[[location(0)]] position: vec3<f32>;
|
[[location(0)]] position: vec3<f32>;
|
||||||
|
|
|
@ -122,7 +122,7 @@ impl FromWorld for ShadowShaders {
|
||||||
// View
|
// View
|
||||||
BindGroupLayoutEntry {
|
BindGroupLayoutEntry {
|
||||||
binding: 0,
|
binding: 0,
|
||||||
visibility: ShaderStage::VERTEX | ShaderStage::FRAGMENT,
|
visibility: ShaderStages::VERTEX | ShaderStages::FRAGMENT,
|
||||||
ty: BindingType::Buffer {
|
ty: BindingType::Buffer {
|
||||||
ty: BufferBindingType::Uniform,
|
ty: BufferBindingType::Uniform,
|
||||||
has_dynamic_offset: true,
|
has_dynamic_offset: true,
|
||||||
|
@ -147,7 +147,7 @@ impl FromWorld for ShadowShaders {
|
||||||
vertex: VertexState {
|
vertex: VertexState {
|
||||||
buffers: &[VertexBufferLayout {
|
buffers: &[VertexBufferLayout {
|
||||||
array_stride: 32,
|
array_stride: 32,
|
||||||
step_mode: InputStepMode::Vertex,
|
step_mode: VertexStepMode::Vertex,
|
||||||
attributes: &[
|
attributes: &[
|
||||||
// Position (GOTCHA! Vertex_Position isn't first in the buffer due to how Mesh sorts attributes (alphabetically))
|
// Position (GOTCHA! Vertex_Position isn't first in the buffer due to how Mesh sorts attributes (alphabetically))
|
||||||
VertexAttribute {
|
VertexAttribute {
|
||||||
|
@ -411,8 +411,8 @@ pub fn prepare_lights(
|
||||||
sample_count: 1,
|
sample_count: 1,
|
||||||
dimension: TextureDimension::D2,
|
dimension: TextureDimension::D2,
|
||||||
format: SHADOW_FORMAT,
|
format: SHADOW_FORMAT,
|
||||||
usage: TextureUsage::RENDER_ATTACHMENT | TextureUsage::SAMPLED,
|
|
||||||
label: Some("point_light_shadow_map_texture"),
|
label: Some("point_light_shadow_map_texture"),
|
||||||
|
usage: TextureUsages::RENDER_ATTACHMENT | TextureUsages::TEXTURE_BINDING,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let directional_light_depth_texture = texture_cache.get(
|
let directional_light_depth_texture = texture_cache.get(
|
||||||
|
@ -427,8 +427,8 @@ pub fn prepare_lights(
|
||||||
sample_count: 1,
|
sample_count: 1,
|
||||||
dimension: TextureDimension::D2,
|
dimension: TextureDimension::D2,
|
||||||
format: SHADOW_FORMAT,
|
format: SHADOW_FORMAT,
|
||||||
usage: TextureUsage::RENDER_ATTACHMENT | TextureUsage::SAMPLED,
|
|
||||||
label: Some("directional_light_shadow_map_texture"),
|
label: Some("directional_light_shadow_map_texture"),
|
||||||
|
usage: TextureUsages::RENDER_ATTACHMENT | TextureUsages::TEXTURE_BINDING,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let mut view_lights = Vec::new();
|
let mut view_lights = Vec::new();
|
||||||
|
|
|
@ -136,7 +136,7 @@ impl FromWorld for PbrShaders {
|
||||||
// View
|
// View
|
||||||
BindGroupLayoutEntry {
|
BindGroupLayoutEntry {
|
||||||
binding: 0,
|
binding: 0,
|
||||||
visibility: ShaderStage::VERTEX | ShaderStage::FRAGMENT,
|
visibility: ShaderStages::VERTEX | ShaderStages::FRAGMENT,
|
||||||
ty: BindingType::Buffer {
|
ty: BindingType::Buffer {
|
||||||
ty: BufferBindingType::Uniform,
|
ty: BufferBindingType::Uniform,
|
||||||
has_dynamic_offset: true,
|
has_dynamic_offset: true,
|
||||||
|
@ -149,7 +149,7 @@ impl FromWorld for PbrShaders {
|
||||||
// Lights
|
// Lights
|
||||||
BindGroupLayoutEntry {
|
BindGroupLayoutEntry {
|
||||||
binding: 1,
|
binding: 1,
|
||||||
visibility: ShaderStage::FRAGMENT,
|
visibility: ShaderStages::FRAGMENT,
|
||||||
ty: BindingType::Buffer {
|
ty: BindingType::Buffer {
|
||||||
ty: BufferBindingType::Uniform,
|
ty: BufferBindingType::Uniform,
|
||||||
has_dynamic_offset: true,
|
has_dynamic_offset: true,
|
||||||
|
@ -162,7 +162,7 @@ impl FromWorld for PbrShaders {
|
||||||
// Point Shadow Texture Cube Array
|
// Point Shadow Texture Cube Array
|
||||||
BindGroupLayoutEntry {
|
BindGroupLayoutEntry {
|
||||||
binding: 2,
|
binding: 2,
|
||||||
visibility: ShaderStage::FRAGMENT,
|
visibility: ShaderStages::FRAGMENT,
|
||||||
ty: BindingType::Texture {
|
ty: BindingType::Texture {
|
||||||
multisampled: false,
|
multisampled: false,
|
||||||
sample_type: TextureSampleType::Depth,
|
sample_type: TextureSampleType::Depth,
|
||||||
|
@ -173,7 +173,7 @@ impl FromWorld for PbrShaders {
|
||||||
// Point Shadow Texture Array Sampler
|
// Point Shadow Texture Array Sampler
|
||||||
BindGroupLayoutEntry {
|
BindGroupLayoutEntry {
|
||||||
binding: 3,
|
binding: 3,
|
||||||
visibility: ShaderStage::FRAGMENT,
|
visibility: ShaderStages::FRAGMENT,
|
||||||
ty: BindingType::Sampler {
|
ty: BindingType::Sampler {
|
||||||
comparison: true,
|
comparison: true,
|
||||||
filtering: true,
|
filtering: true,
|
||||||
|
@ -183,7 +183,7 @@ impl FromWorld for PbrShaders {
|
||||||
// Directional Shadow Texture Array
|
// Directional Shadow Texture Array
|
||||||
BindGroupLayoutEntry {
|
BindGroupLayoutEntry {
|
||||||
binding: 4,
|
binding: 4,
|
||||||
visibility: ShaderStage::FRAGMENT,
|
visibility: ShaderStages::FRAGMENT,
|
||||||
ty: BindingType::Texture {
|
ty: BindingType::Texture {
|
||||||
multisampled: false,
|
multisampled: false,
|
||||||
sample_type: TextureSampleType::Depth,
|
sample_type: TextureSampleType::Depth,
|
||||||
|
@ -194,7 +194,7 @@ impl FromWorld for PbrShaders {
|
||||||
// Directional Shadow Texture Array Sampler
|
// Directional Shadow Texture Array Sampler
|
||||||
BindGroupLayoutEntry {
|
BindGroupLayoutEntry {
|
||||||
binding: 5,
|
binding: 5,
|
||||||
visibility: ShaderStage::FRAGMENT,
|
visibility: ShaderStages::FRAGMENT,
|
||||||
ty: BindingType::Sampler {
|
ty: BindingType::Sampler {
|
||||||
comparison: true,
|
comparison: true,
|
||||||
filtering: true,
|
filtering: true,
|
||||||
|
@ -209,7 +209,7 @@ impl FromWorld for PbrShaders {
|
||||||
entries: &[
|
entries: &[
|
||||||
BindGroupLayoutEntry {
|
BindGroupLayoutEntry {
|
||||||
binding: 0,
|
binding: 0,
|
||||||
visibility: ShaderStage::FRAGMENT,
|
visibility: ShaderStages::FRAGMENT,
|
||||||
ty: BindingType::Buffer {
|
ty: BindingType::Buffer {
|
||||||
ty: BufferBindingType::Uniform,
|
ty: BufferBindingType::Uniform,
|
||||||
has_dynamic_offset: false,
|
has_dynamic_offset: false,
|
||||||
|
@ -222,7 +222,7 @@ impl FromWorld for PbrShaders {
|
||||||
// Base Color Texture
|
// Base Color Texture
|
||||||
BindGroupLayoutEntry {
|
BindGroupLayoutEntry {
|
||||||
binding: 1,
|
binding: 1,
|
||||||
visibility: ShaderStage::FRAGMENT,
|
visibility: ShaderStages::FRAGMENT,
|
||||||
ty: BindingType::Texture {
|
ty: BindingType::Texture {
|
||||||
multisampled: false,
|
multisampled: false,
|
||||||
sample_type: TextureSampleType::Float { filterable: true },
|
sample_type: TextureSampleType::Float { filterable: true },
|
||||||
|
@ -233,7 +233,7 @@ impl FromWorld for PbrShaders {
|
||||||
// Base Color Texture Sampler
|
// Base Color Texture Sampler
|
||||||
BindGroupLayoutEntry {
|
BindGroupLayoutEntry {
|
||||||
binding: 2,
|
binding: 2,
|
||||||
visibility: ShaderStage::FRAGMENT,
|
visibility: ShaderStages::FRAGMENT,
|
||||||
ty: BindingType::Sampler {
|
ty: BindingType::Sampler {
|
||||||
comparison: false,
|
comparison: false,
|
||||||
filtering: true,
|
filtering: true,
|
||||||
|
@ -243,7 +243,7 @@ impl FromWorld for PbrShaders {
|
||||||
// Emissive Texture
|
// Emissive Texture
|
||||||
BindGroupLayoutEntry {
|
BindGroupLayoutEntry {
|
||||||
binding: 3,
|
binding: 3,
|
||||||
visibility: ShaderStage::FRAGMENT,
|
visibility: ShaderStages::FRAGMENT,
|
||||||
ty: BindingType::Texture {
|
ty: BindingType::Texture {
|
||||||
multisampled: false,
|
multisampled: false,
|
||||||
sample_type: TextureSampleType::Float { filterable: true },
|
sample_type: TextureSampleType::Float { filterable: true },
|
||||||
|
@ -254,7 +254,7 @@ impl FromWorld for PbrShaders {
|
||||||
// Emissive Texture Sampler
|
// Emissive Texture Sampler
|
||||||
BindGroupLayoutEntry {
|
BindGroupLayoutEntry {
|
||||||
binding: 4,
|
binding: 4,
|
||||||
visibility: ShaderStage::FRAGMENT,
|
visibility: ShaderStages::FRAGMENT,
|
||||||
ty: BindingType::Sampler {
|
ty: BindingType::Sampler {
|
||||||
comparison: false,
|
comparison: false,
|
||||||
filtering: true,
|
filtering: true,
|
||||||
|
@ -264,7 +264,7 @@ impl FromWorld for PbrShaders {
|
||||||
// Metallic Roughness Texture
|
// Metallic Roughness Texture
|
||||||
BindGroupLayoutEntry {
|
BindGroupLayoutEntry {
|
||||||
binding: 5,
|
binding: 5,
|
||||||
visibility: ShaderStage::FRAGMENT,
|
visibility: ShaderStages::FRAGMENT,
|
||||||
ty: BindingType::Texture {
|
ty: BindingType::Texture {
|
||||||
multisampled: false,
|
multisampled: false,
|
||||||
sample_type: TextureSampleType::Float { filterable: true },
|
sample_type: TextureSampleType::Float { filterable: true },
|
||||||
|
@ -275,7 +275,7 @@ impl FromWorld for PbrShaders {
|
||||||
// Metallic Roughness Texture Sampler
|
// Metallic Roughness Texture Sampler
|
||||||
BindGroupLayoutEntry {
|
BindGroupLayoutEntry {
|
||||||
binding: 6,
|
binding: 6,
|
||||||
visibility: ShaderStage::FRAGMENT,
|
visibility: ShaderStages::FRAGMENT,
|
||||||
ty: BindingType::Sampler {
|
ty: BindingType::Sampler {
|
||||||
comparison: false,
|
comparison: false,
|
||||||
filtering: true,
|
filtering: true,
|
||||||
|
@ -285,7 +285,7 @@ impl FromWorld for PbrShaders {
|
||||||
// Occlusion Texture
|
// Occlusion Texture
|
||||||
BindGroupLayoutEntry {
|
BindGroupLayoutEntry {
|
||||||
binding: 7,
|
binding: 7,
|
||||||
visibility: ShaderStage::FRAGMENT,
|
visibility: ShaderStages::FRAGMENT,
|
||||||
ty: BindingType::Texture {
|
ty: BindingType::Texture {
|
||||||
multisampled: false,
|
multisampled: false,
|
||||||
sample_type: TextureSampleType::Float { filterable: true },
|
sample_type: TextureSampleType::Float { filterable: true },
|
||||||
|
@ -296,7 +296,7 @@ impl FromWorld for PbrShaders {
|
||||||
// Occlusion Texture Sampler
|
// Occlusion Texture Sampler
|
||||||
BindGroupLayoutEntry {
|
BindGroupLayoutEntry {
|
||||||
binding: 8,
|
binding: 8,
|
||||||
visibility: ShaderStage::FRAGMENT,
|
visibility: ShaderStages::FRAGMENT,
|
||||||
ty: BindingType::Sampler {
|
ty: BindingType::Sampler {
|
||||||
comparison: false,
|
comparison: false,
|
||||||
filtering: true,
|
filtering: true,
|
||||||
|
@ -310,7 +310,7 @@ impl FromWorld for PbrShaders {
|
||||||
let mesh_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
|
let mesh_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
|
||||||
entries: &[BindGroupLayoutEntry {
|
entries: &[BindGroupLayoutEntry {
|
||||||
binding: 0,
|
binding: 0,
|
||||||
visibility: ShaderStage::VERTEX | ShaderStage::FRAGMENT,
|
visibility: ShaderStages::VERTEX | ShaderStages::FRAGMENT,
|
||||||
ty: BindingType::Buffer {
|
ty: BindingType::Buffer {
|
||||||
ty: BufferBindingType::Uniform,
|
ty: BufferBindingType::Uniform,
|
||||||
has_dynamic_offset: true,
|
has_dynamic_offset: true,
|
||||||
|
@ -334,7 +334,7 @@ impl FromWorld for PbrShaders {
|
||||||
vertex: VertexState {
|
vertex: VertexState {
|
||||||
buffers: &[VertexBufferLayout {
|
buffers: &[VertexBufferLayout {
|
||||||
array_stride: 32,
|
array_stride: 32,
|
||||||
step_mode: InputStepMode::Vertex,
|
step_mode: VertexStepMode::Vertex,
|
||||||
attributes: &[
|
attributes: &[
|
||||||
// Position (GOTCHA! Vertex_Position isn't first in the buffer due to how Mesh sorts attributes (alphabetically))
|
// Position (GOTCHA! Vertex_Position isn't first in the buffer due to how Mesh sorts attributes (alphabetically))
|
||||||
VertexAttribute {
|
VertexAttribute {
|
||||||
|
@ -376,7 +376,7 @@ impl FromWorld for PbrShaders {
|
||||||
operation: BlendOperation::Add,
|
operation: BlendOperation::Add,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
write_mask: ColorWrite::ALL,
|
write_mask: ColorWrites::ALL,
|
||||||
}],
|
}],
|
||||||
}),
|
}),
|
||||||
depth_stencil: Some(DepthStencilState {
|
depth_stencil: Some(DepthStencilState {
|
||||||
|
@ -426,6 +426,7 @@ impl FromWorld for PbrShaders {
|
||||||
texture: &texture,
|
texture: &texture,
|
||||||
mip_level: 0,
|
mip_level: 0,
|
||||||
origin: Origin3d::ZERO,
|
origin: Origin3d::ZERO,
|
||||||
|
aspect: wgpu::TextureAspect::All,
|
||||||
},
|
},
|
||||||
&image.data,
|
&image.data,
|
||||||
ImageDataLayout {
|
ImageDataLayout {
|
||||||
|
|
|
@ -18,9 +18,9 @@ struct Mesh {
|
||||||
let MESH_FLAGS_SHADOW_RECEIVER_BIT: u32 = 1u;
|
let MESH_FLAGS_SHADOW_RECEIVER_BIT: u32 = 1u;
|
||||||
|
|
||||||
[[group(0), binding(0)]]
|
[[group(0), binding(0)]]
|
||||||
var view: View;
|
var<uniform> view: View;
|
||||||
[[group(2), binding(0)]]
|
[[group(2), binding(0)]]
|
||||||
var mesh: Mesh;
|
var<uniform> mesh: Mesh;
|
||||||
|
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
[[location(0)]] position: vec3<f32>;
|
[[location(0)]] position: vec3<f32>;
|
||||||
|
@ -136,7 +136,7 @@ struct Lights {
|
||||||
|
|
||||||
|
|
||||||
[[group(0), binding(1)]]
|
[[group(0), binding(1)]]
|
||||||
var lights: Lights;
|
var<uniform> lights: Lights;
|
||||||
[[group(0), binding(2)]]
|
[[group(0), binding(2)]]
|
||||||
var point_shadow_textures: texture_depth_cube_array;
|
var point_shadow_textures: texture_depth_cube_array;
|
||||||
[[group(0), binding(3)]]
|
[[group(0), binding(3)]]
|
||||||
|
@ -147,7 +147,7 @@ var directional_shadow_textures: texture_depth_2d_array;
|
||||||
var directional_shadow_textures_sampler: sampler_comparison;
|
var directional_shadow_textures_sampler: sampler_comparison;
|
||||||
|
|
||||||
[[group(1), binding(0)]]
|
[[group(1), binding(0)]]
|
||||||
var material: StandardMaterial;
|
var<uniform> material: StandardMaterial;
|
||||||
[[group(1), binding(1)]]
|
[[group(1), binding(1)]]
|
||||||
var base_color_texture: texture_2d<f32>;
|
var base_color_texture: texture_2d<f32>;
|
||||||
[[group(1), binding(2)]]
|
[[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> {
|
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);
|
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> {
|
fn reinhard_luminance(color: vec3<f32>) -> vec3<f32> {
|
||||||
let l_old = luminance(color);
|
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);
|
return change_luminance(color, l_new);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reinhard_extended_luminance(color: vec3<f32>, max_white_l: f32) -> vec3<f32> {
|
fn reinhard_extended_luminance(color: vec3<f32>, max_white_l: f32) -> vec3<f32> {
|
||||||
let l_old = luminance(color);
|
let l_old = luminance(color);
|
||||||
let numerator = l_old * (1.0f + (l_old / (max_white_l * max_white_l)));
|
let numerator = l_old * (1.0 + (l_old / (max_white_l * max_white_l)));
|
||||||
let l_new = numerator / (1.0f + l_old);
|
let l_new = numerator / (1.0 + l_old);
|
||||||
return change_luminance(color, l_new);
|
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 }
|
image = { version = "0.23.12", default-features = false }
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
wgpu = "0.9"
|
wgpu = { version = "0.11.0", features = ["spirv"] }
|
||||||
naga = { version = "0.5", features = ["glsl-in", "spv-in", "spv-out", "wgsl-in", "wgsl-out"] }
|
naga = { version = "0.7.0", features = ["glsl-in", "spv-in", "spv-out", "wgsl-in", "wgsl-out"] }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
bitflags = "1.2.1"
|
bitflags = "1.2.1"
|
||||||
smallvec = { version = "1.6", features = ["union", "const_generics"] }
|
smallvec = { version = "1.6", features = ["union", "const_generics"] }
|
||||||
|
|
|
@ -25,7 +25,7 @@ use bevy_app::{App, AppLabel, Plugin};
|
||||||
use bevy_asset::AssetServer;
|
use bevy_asset::AssetServer;
|
||||||
use bevy_ecs::prelude::*;
|
use bevy_ecs::prelude::*;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use wgpu::BackendBit;
|
use wgpu::Backends;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct RenderPlugin;
|
pub struct RenderPlugin;
|
||||||
|
@ -86,7 +86,7 @@ impl Plugin for RenderPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
let (instance, device, queue) =
|
let (instance, device, queue) =
|
||||||
futures_lite::future::block_on(renderer::initialize_renderer(
|
futures_lite::future::block_on(renderer::initialize_renderer(
|
||||||
BackendBit::PRIMARY,
|
wgpu::util::backend_bits_from_env().unwrap_or(Backends::PRIMARY),
|
||||||
&wgpu::RequestAdapterOptions {
|
&wgpu::RequestAdapterOptions {
|
||||||
power_preference: wgpu::PowerPreference::HighPerformance,
|
power_preference: wgpu::PowerPreference::HighPerformance,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
|
@ -11,7 +11,9 @@ use bevy_math::*;
|
||||||
use bevy_reflect::TypeUuid;
|
use bevy_reflect::TypeUuid;
|
||||||
use bevy_utils::EnumVariantMeta;
|
use bevy_utils::EnumVariantMeta;
|
||||||
use std::{borrow::Cow, collections::BTreeMap};
|
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 INDEX_BUFFER_ASSET_INDEX: u64 = 0;
|
||||||
pub const VERTEX_ATTRIBUTE_BUFFER_ID: u64 = 10;
|
pub const VERTEX_ATTRIBUTE_BUFFER_ID: u64 = 10;
|
||||||
|
@ -553,14 +555,14 @@ impl RenderAsset for Mesh {
|
||||||
) -> Result<Self::PreparedAsset, PrepareAssetError<Self::ExtractedAsset>> {
|
) -> Result<Self::PreparedAsset, PrepareAssetError<Self::ExtractedAsset>> {
|
||||||
let vertex_buffer_data = mesh.get_vertex_buffer_data();
|
let vertex_buffer_data = mesh.get_vertex_buffer_data();
|
||||||
let vertex_buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
|
let vertex_buffer = render_device.create_buffer_with_data(&BufferInitDescriptor {
|
||||||
usage: BufferUsage::VERTEX,
|
usage: BufferUsages::VERTEX,
|
||||||
label: None,
|
label: None,
|
||||||
contents: &vertex_buffer_data,
|
contents: &vertex_buffer_data,
|
||||||
});
|
});
|
||||||
|
|
||||||
let index_info = mesh.get_index_buffer_bytes().map(|data| GpuIndexInfo {
|
let index_info = mesh.get_index_buffer_bytes().map(|data| GpuIndexInfo {
|
||||||
buffer: render_device.create_buffer_with_data(&BufferInitDescriptor {
|
buffer: render_device.create_buffer_with_data(&BufferInitDescriptor {
|
||||||
usage: BufferUsage::INDEX,
|
usage: BufferUsages::INDEX,
|
||||||
contents: data,
|
contents: data,
|
||||||
label: None,
|
label: None,
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -3,14 +3,14 @@ use crate::{
|
||||||
renderer::{RenderDevice, RenderQueue},
|
renderer::{RenderDevice, RenderQueue},
|
||||||
};
|
};
|
||||||
use bevy_core::{cast_slice, Pod};
|
use bevy_core::{cast_slice, Pod};
|
||||||
use wgpu::BufferUsage;
|
use wgpu::BufferUsages;
|
||||||
|
|
||||||
pub struct BufferVec<T: Pod> {
|
pub struct BufferVec<T: Pod> {
|
||||||
values: Vec<T>,
|
values: Vec<T>,
|
||||||
buffer: Option<Buffer>,
|
buffer: Option<Buffer>,
|
||||||
capacity: usize,
|
capacity: usize,
|
||||||
item_size: usize,
|
item_size: usize,
|
||||||
buffer_usage: BufferUsage,
|
buffer_usage: BufferUsages,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Pod> Default for BufferVec<T> {
|
impl<T: Pod> Default for BufferVec<T> {
|
||||||
|
@ -19,14 +19,14 @@ impl<T: Pod> Default for BufferVec<T> {
|
||||||
values: Vec::new(),
|
values: Vec::new(),
|
||||||
buffer: None,
|
buffer: None,
|
||||||
capacity: 0,
|
capacity: 0,
|
||||||
buffer_usage: BufferUsage::all(),
|
buffer_usage: BufferUsages::all(),
|
||||||
item_size: std::mem::size_of::<T>(),
|
item_size: std::mem::size_of::<T>(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Pod> BufferVec<T> {
|
impl<T: Pod> BufferVec<T> {
|
||||||
pub fn new(buffer_usage: BufferUsage) -> Self {
|
pub fn new(buffer_usage: BufferUsages) -> Self {
|
||||||
Self {
|
Self {
|
||||||
buffer_usage,
|
buffer_usage,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
@ -63,7 +63,7 @@ impl<T: Pod> BufferVec<T> {
|
||||||
self.buffer = Some(device.create_buffer(&wgpu::BufferDescriptor {
|
self.buffer = Some(device.create_buffer(&wgpu::BufferDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
size: size as wgpu::BufferAddress,
|
size: size as wgpu::BufferAddress,
|
||||||
usage: BufferUsage::COPY_DST | self.buffer_usage,
|
usage: BufferUsages::COPY_DST | self.buffer_usage,
|
||||||
mapped_at_creation: false,
|
mapped_at_creation: false,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,14 +17,14 @@ pub use wgpu::{
|
||||||
util::BufferInitDescriptor, AddressMode, BindGroupDescriptor, BindGroupEntry, BindGroupLayout,
|
util::BufferInitDescriptor, AddressMode, BindGroupDescriptor, BindGroupEntry, BindGroupLayout,
|
||||||
BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingResource, BindingType, BlendComponent,
|
BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingResource, BindingType, BlendComponent,
|
||||||
BlendFactor, BlendOperation, BlendState, BufferAddress, BufferBindingType, BufferSize,
|
BlendFactor, BlendOperation, BlendState, BufferAddress, BufferBindingType, BufferSize,
|
||||||
BufferUsage, ColorTargetState, ColorWrite, CompareFunction, ComputePassDescriptor,
|
BufferUsages, ColorTargetState, ColorWrites, CompareFunction, ComputePassDescriptor,
|
||||||
ComputePipelineDescriptor, DepthBiasState, DepthStencilState, Extent3d, Face, FilterMode,
|
ComputePipelineDescriptor, DepthBiasState, DepthStencilState, Extent3d, Face, FilterMode,
|
||||||
FragmentState, FrontFace, IndexFormat, InputStepMode, LoadOp, MultisampleState, Operations,
|
FragmentState, FrontFace, IndexFormat, LoadOp, MultisampleState, Operations, PipelineLayout,
|
||||||
PipelineLayout, PipelineLayoutDescriptor, PolygonMode, PrimitiveState, PrimitiveTopology,
|
PipelineLayoutDescriptor, PolygonMode, PrimitiveState, PrimitiveTopology,
|
||||||
RenderPassColorAttachment, RenderPassDepthStencilAttachment, RenderPassDescriptor,
|
RenderPassColorAttachment, RenderPassDepthStencilAttachment, RenderPassDescriptor,
|
||||||
RenderPipelineDescriptor, SamplerDescriptor, ShaderFlags, ShaderModule, ShaderModuleDescriptor,
|
RenderPipelineDescriptor, SamplerDescriptor, ShaderModule, ShaderModuleDescriptor,
|
||||||
ShaderSource, ShaderStage, StencilFaceState, StencilOperation, StencilState,
|
ShaderSource, ShaderStages, StencilFaceState, StencilOperation, StencilState,
|
||||||
StorageTextureAccess, TextureAspect, TextureDescriptor, TextureDimension, TextureFormat,
|
StorageTextureAccess, TextureAspect, TextureDescriptor, TextureDimension, TextureFormat,
|
||||||
TextureSampleType, TextureUsage, TextureViewDescriptor, TextureViewDimension, VertexAttribute,
|
TextureSampleType, TextureUsages, TextureViewDescriptor, TextureViewDimension, VertexAttribute,
|
||||||
VertexBufferLayout, VertexFormat, VertexState,
|
VertexBufferLayout, VertexFormat, VertexState, VertexStepMode,
|
||||||
};
|
};
|
||||||
|
|
|
@ -45,7 +45,12 @@ pub struct TextureViewId(Uuid);
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum TextureViewValue {
|
pub enum TextureViewValue {
|
||||||
TextureView(Arc<wgpu::TextureView>),
|
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)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -59,6 +64,14 @@ impl TextureView {
|
||||||
pub fn id(&self) -> TextureViewId {
|
pub fn id(&self) -> TextureViewId {
|
||||||
self.id
|
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 {
|
impl From<wgpu::TextureView> for TextureView {
|
||||||
|
@ -70,11 +83,14 @@ impl From<wgpu::TextureView> for TextureView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<wgpu::SwapChainFrame> for TextureView {
|
impl From<wgpu::SurfaceTexture> for TextureView {
|
||||||
fn from(value: wgpu::SwapChainFrame) -> Self {
|
fn from(value: wgpu::SurfaceTexture) -> Self {
|
||||||
|
let texture = Arc::new(value);
|
||||||
|
let view = Arc::new(texture.texture.create_view(&Default::default()));
|
||||||
|
|
||||||
TextureView {
|
TextureView {
|
||||||
id: TextureViewId(Uuid::new_v4()),
|
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 {
|
fn deref(&self) -> &Self::Target {
|
||||||
match &self.value {
|
match &self.value {
|
||||||
TextureViewValue::TextureView(value) => 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 crevice::std140::{self, AsStd140, DynamicUniform, Std140};
|
||||||
use std::num::NonZeroU64;
|
use std::num::NonZeroU64;
|
||||||
use wgpu::{BindingResource, BufferBinding, BufferDescriptor, BufferUsage};
|
use wgpu::{BindingResource, BufferBinding, BufferDescriptor, BufferUsages};
|
||||||
|
|
||||||
pub struct UniformVec<T: AsStd140> {
|
pub struct UniformVec<T: AsStd140> {
|
||||||
values: Vec<T>,
|
values: Vec<T>,
|
||||||
|
@ -78,7 +78,7 @@ impl<T: AsStd140> UniformVec<T> {
|
||||||
self.uniform_buffer = Some(device.create_buffer(&BufferDescriptor {
|
self.uniform_buffer = Some(device.create_buffer(&BufferDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
size: size as wgpu::BufferAddress,
|
size: size as wgpu::BufferAddress,
|
||||||
usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
|
usage: BufferUsages::COPY_DST | BufferUsages::UNIFORM,
|
||||||
mapped_at_creation: false,
|
mapped_at_creation: false,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
mod graph_runner;
|
mod graph_runner;
|
||||||
mod render_device;
|
mod render_device;
|
||||||
|
|
||||||
use bevy_utils::tracing::info;
|
use bevy_utils::tracing::{info, info_span};
|
||||||
pub use graph_runner::*;
|
pub use graph_runner::*;
|
||||||
pub use render_device::*;
|
pub use render_device::*;
|
||||||
|
|
||||||
use crate::render_graph::RenderGraph;
|
use crate::{render_graph::RenderGraph, view::ExtractedWindows};
|
||||||
use bevy_ecs::prelude::*;
|
use bevy_ecs::prelude::*;
|
||||||
use std::sync::Arc;
|
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) {
|
pub fn render_system(world: &mut World) {
|
||||||
world.resource_scope(|world, mut graph: Mut<RenderGraph>| {
|
world.resource_scope(|world, mut graph: Mut<RenderGraph>| {
|
||||||
|
@ -24,13 +24,25 @@ pub fn render_system(world: &mut World) {
|
||||||
world,
|
world,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.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 RenderQueue = Arc<Queue>;
|
||||||
pub type RenderInstance = Instance;
|
pub type RenderInstance = Instance;
|
||||||
|
|
||||||
pub async fn initialize_renderer(
|
pub async fn initialize_renderer(
|
||||||
backends: BackendBit,
|
backends: Backends,
|
||||||
request_adapter_options: &RequestAdapterOptions<'_>,
|
request_adapter_options: &RequestAdapterOptions<'_>,
|
||||||
device_descriptor: &DeviceDescriptor<'_>,
|
device_descriptor: &DeviceDescriptor<'_>,
|
||||||
) -> (RenderInstance, RenderDevice, RenderQueue) {
|
) -> (RenderInstance, RenderDevice, RenderQueue) {
|
||||||
|
|
|
@ -145,12 +145,8 @@ impl RenderDevice {
|
||||||
///
|
///
|
||||||
/// - A old [`SwapChainFrame`] is still alive referencing an old swapchain.
|
/// - A old [`SwapChainFrame`] is still alive referencing an old swapchain.
|
||||||
/// - Texture format requested is unsupported on the swap chain.
|
/// - Texture format requested is unsupported on the swap chain.
|
||||||
pub fn create_swap_chain(
|
pub fn configure_surface(&self, surface: &wgpu::Surface, config: &wgpu::SurfaceConfiguration) {
|
||||||
&self,
|
surface.configure(&self.device, config)
|
||||||
surface: &wgpu::Surface,
|
|
||||||
desc: &wgpu::SwapChainDescriptor,
|
|
||||||
) -> wgpu::SwapChain {
|
|
||||||
self.device.create_swap_chain(surface, desc)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wgpu_device(&self) -> &wgpu::Device {
|
pub fn wgpu_device(&self) -> &wgpu::Device {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use bevy_asset::{AssetLoader, LoadContext, LoadedAsset};
|
use bevy_asset::{AssetLoader, LoadContext, LoadedAsset};
|
||||||
use bevy_reflect::{TypeUuid, Uuid};
|
use bevy_reflect::{TypeUuid, Uuid};
|
||||||
use bevy_utils::{tracing::error, BoxedFuture};
|
use bevy_utils::{tracing::error, BoxedFuture};
|
||||||
use naga::{valid::ModuleInfo, Module, ShaderStage};
|
use naga::{valid::ModuleInfo, Module};
|
||||||
use std::{borrow::Cow, collections::HashMap, marker::Copy};
|
use std::{borrow::Cow, marker::Copy};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use wgpu::{ShaderFlags, ShaderModuleDescriptor, ShaderSource};
|
use wgpu::{ShaderModuleDescriptor, ShaderSource};
|
||||||
|
|
||||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
||||||
pub struct ShaderId(Uuid);
|
pub struct ShaderId(Uuid);
|
||||||
|
@ -20,8 +20,8 @@ impl ShaderId {
|
||||||
pub enum ShaderReflectError {
|
pub enum ShaderReflectError {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
WgslParse(#[from] naga::front::wgsl::ParseError),
|
WgslParse(#[from] naga::front::wgsl::ParseError),
|
||||||
#[error(transparent)]
|
#[error("GLSL Parse Error: {0:?}")]
|
||||||
GlslParse(#[from] naga::front::glsl::ParseError),
|
GlslParse(Vec<naga::front::glsl::Error>),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
SpirVParse(#[from] naga::front::spv::Error),
|
SpirVParse(#[from] naga::front::spv::Error),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
|
@ -33,7 +33,7 @@ pub enum ShaderReflectError {
|
||||||
#[uuid = "d95bc916-6c55-4de3-9622-37e7b6969fda"]
|
#[uuid = "d95bc916-6c55-4de3-9622-37e7b6969fda"]
|
||||||
pub enum Shader {
|
pub enum Shader {
|
||||||
Wgsl(Cow<'static, str>),
|
Wgsl(Cow<'static, str>),
|
||||||
Glsl(Cow<'static, str>),
|
Glsl(Cow<'static, str>, naga::ShaderStage),
|
||||||
SpirV(Vec<u8>),
|
SpirV(Vec<u8>),
|
||||||
// TODO: consider the following
|
// TODO: consider the following
|
||||||
// PrecompiledSpirVMacros(HashMap<HashSet<String>, Vec<u32>>)
|
// PrecompiledSpirVMacros(HashMap<HashSet<String>, Vec<u32>>)
|
||||||
|
@ -54,6 +54,7 @@ impl ShaderReflection {
|
||||||
flags: naga::back::spv::WriterFlags::empty(),
|
flags: naga::back::spv::WriterFlags::empty(),
|
||||||
..naga::back::spv::Options::default()
|
..naga::back::spv::Options::default()
|
||||||
},
|
},
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,17 +68,11 @@ impl Shader {
|
||||||
let module = match &self {
|
let module = match &self {
|
||||||
// TODO: process macros here
|
// TODO: process macros here
|
||||||
Shader::Wgsl(source) => naga::front::wgsl::parse_str(source)?,
|
Shader::Wgsl(source) => naga::front::wgsl::parse_str(source)?,
|
||||||
Shader::Glsl(source) => {
|
Shader::Glsl(source, shader_stage) => {
|
||||||
let mut entry_points = HashMap::default();
|
let mut parser = naga::front::glsl::Parser::default();
|
||||||
entry_points.insert("vertex".to_string(), ShaderStage::Vertex);
|
parser
|
||||||
entry_points.insert("fragment".to_string(), ShaderStage::Fragment);
|
.parse(&naga::front::glsl::Options::from(*shader_stage), source)
|
||||||
naga::front::glsl::parse_str(
|
.map_err(ShaderReflectError::GlslParse)?
|
||||||
source,
|
|
||||||
&naga::front::glsl::Options {
|
|
||||||
entry_points,
|
|
||||||
defines: Default::default(),
|
|
||||||
},
|
|
||||||
)?
|
|
||||||
}
|
}
|
||||||
Shader::SpirV(source) => naga::front::spv::parse_u8_slice(
|
Shader::SpirV(source) => naga::front::spv::parse_u8_slice(
|
||||||
source,
|
source,
|
||||||
|
@ -103,8 +98,8 @@ impl Shader {
|
||||||
Shader::Wgsl(source.into())
|
Shader::Wgsl(source.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_glsl(source: impl Into<Cow<'static, str>>) -> Shader {
|
pub fn from_glsl(source: impl Into<Cow<'static, str>>, stage: naga::ShaderStage) -> Shader {
|
||||||
Shader::Glsl(source.into())
|
Shader::Glsl(source.into(), stage)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_spirv(source: Vec<u8>) -> Shader {
|
pub fn from_spirv(source: Vec<u8>) -> Shader {
|
||||||
|
@ -143,11 +138,10 @@ impl AssetLoader for ShaderLoader {
|
||||||
impl<'a> From<&'a Shader> for ShaderModuleDescriptor<'a> {
|
impl<'a> From<&'a Shader> for ShaderModuleDescriptor<'a> {
|
||||||
fn from(shader: &'a Shader) -> Self {
|
fn from(shader: &'a Shader) -> Self {
|
||||||
ShaderModuleDescriptor {
|
ShaderModuleDescriptor {
|
||||||
flags: ShaderFlags::default(),
|
|
||||||
label: None,
|
label: None,
|
||||||
source: match shader {
|
source: match shader {
|
||||||
Shader::Wgsl(source) => ShaderSource::Wgsl(source.clone()),
|
Shader::Wgsl(source) => ShaderSource::Wgsl(source.clone()),
|
||||||
Shader::Glsl(_source) => {
|
Shader::Glsl(_source, _stage) => {
|
||||||
let reflection = shader.reflect().unwrap();
|
let reflection = shader.reflect().unwrap();
|
||||||
let wgsl = reflection.get_wgsl().unwrap();
|
let wgsl = reflection.get_wgsl().unwrap();
|
||||||
ShaderSource::Wgsl(wgsl.into())
|
ShaderSource::Wgsl(wgsl.into())
|
||||||
|
|
|
@ -42,7 +42,7 @@ impl Default for Image {
|
||||||
label: None,
|
label: None,
|
||||||
mip_level_count: 1,
|
mip_level_count: 1,
|
||||||
sample_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(),
|
sampler_descriptor: wgpu::SamplerDescriptor::default(),
|
||||||
}
|
}
|
||||||
|
@ -369,6 +369,7 @@ impl RenderAsset for Image {
|
||||||
texture: &texture,
|
texture: &texture,
|
||||||
mip_level: 0,
|
mip_level: 0,
|
||||||
origin: Origin3d::ZERO,
|
origin: Origin3d::ZERO,
|
||||||
|
aspect: wgpu::TextureAspect::All,
|
||||||
},
|
},
|
||||||
&image.data,
|
&image.data,
|
||||||
ImageDataLayout {
|
ImageDataLayout {
|
||||||
|
|
|
@ -6,7 +6,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
use bevy_app::{App, Plugin};
|
use bevy_app::{App, Plugin};
|
||||||
use bevy_ecs::prelude::*;
|
use bevy_ecs::prelude::*;
|
||||||
use bevy_utils::{tracing::debug, HashMap};
|
use bevy_utils::{tracing::debug, HashMap, HashSet};
|
||||||
use bevy_window::{RawWindowHandleWrapper, WindowId, Windows};
|
use bevy_window::{RawWindowHandleWrapper, WindowId, Windows};
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use wgpu::TextureFormat;
|
use wgpu::TextureFormat;
|
||||||
|
@ -34,7 +34,7 @@ pub struct ExtractedWindow {
|
||||||
pub physical_width: u32,
|
pub physical_width: u32,
|
||||||
pub physical_height: u32,
|
pub physical_height: u32,
|
||||||
pub vsync: bool,
|
pub vsync: bool,
|
||||||
pub swap_chain_frame: Option<TextureView>,
|
pub swap_chain_texture: Option<TextureView>,
|
||||||
pub size_changed: bool,
|
pub size_changed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,12 +74,12 @@ fn extract_windows(mut render_world: ResMut<RenderWorld>, windows: Res<Windows>)
|
||||||
physical_width: new_width,
|
physical_width: new_width,
|
||||||
physical_height: new_height,
|
physical_height: new_height,
|
||||||
vsync: window.vsync(),
|
vsync: window.vsync(),
|
||||||
swap_chain_frame: None,
|
swap_chain_texture: None,
|
||||||
size_changed: false,
|
size_changed: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// NOTE: Drop the swap chain frame here
|
// 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
|
extracted_window.size_changed = new_width != extracted_window.physical_width
|
||||||
|| new_height != extracted_window.physical_height;
|
|| new_height != extracted_window.physical_height;
|
||||||
|
|
||||||
|
@ -100,7 +100,8 @@ fn extract_windows(mut render_world: ResMut<RenderWorld>, windows: Res<Windows>)
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct WindowSurfaces {
|
pub struct WindowSurfaces {
|
||||||
surfaces: HashMap<WindowId, wgpu::Surface>,
|
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(
|
pub fn prepare_windows(
|
||||||
|
@ -122,11 +123,11 @@ pub fn prepare_windows(
|
||||||
render_instance.create_surface(&window.handle.get_handle())
|
render_instance.create_surface(&window.handle.get_handle())
|
||||||
});
|
});
|
||||||
|
|
||||||
let swap_chain_descriptor = wgpu::SwapChainDescriptor {
|
let swap_chain_descriptor = wgpu::SurfaceConfiguration {
|
||||||
format: TextureFormat::bevy_default(),
|
format: TextureFormat::bevy_default(),
|
||||||
width: window.physical_width,
|
width: window.physical_width,
|
||||||
height: window.physical_height,
|
height: window.physical_height,
|
||||||
usage: wgpu::TextureUsage::RENDER_ATTACHMENT,
|
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
|
||||||
present_mode: if window.vsync {
|
present_mode: if window.vsync {
|
||||||
wgpu::PresentMode::Fifo
|
wgpu::PresentMode::Fifo
|
||||||
} else {
|
} else {
|
||||||
|
@ -134,34 +135,22 @@ pub fn prepare_windows(
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if window.size_changed {
|
// Do the initial surface configuration if it hasn't been configured yet
|
||||||
window_surfaces.swap_chains.insert(
|
if window_surfaces.configured_windows.insert(window.id) {
|
||||||
window.id,
|
render_device.configure_surface(surface, &swap_chain_descriptor);
|
||||||
render_device.create_swap_chain(surface, &swap_chain_descriptor),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let swap_chain = window_surfaces
|
let frame = match surface.get_current_texture() {
|
||||||
.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() {
|
|
||||||
Ok(swap_chain_frame) => swap_chain_frame,
|
Ok(swap_chain_frame) => swap_chain_frame,
|
||||||
Err(wgpu::SwapChainError::Outdated) => {
|
Err(wgpu::SurfaceError::Outdated) => {
|
||||||
let new_swap_chain =
|
render_device.configure_surface(surface, &swap_chain_descriptor);
|
||||||
render_device.create_swap_chain(surface, &swap_chain_descriptor);
|
surface
|
||||||
let frame = new_swap_chain
|
.get_current_texture()
|
||||||
.get_current_frame()
|
.expect("Error reconfiguring surface")
|
||||||
.expect("Error recreating swap chain");
|
|
||||||
window_surfaces
|
|
||||||
.swap_chains
|
|
||||||
.insert(window.id, new_swap_chain);
|
|
||||||
frame
|
|
||||||
}
|
}
|
||||||
err => err.expect("Failed to acquire next swap chain texture!"),
|
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 {
|
let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
|
||||||
entries: &[BindGroupLayoutEntry {
|
entries: &[BindGroupLayoutEntry {
|
||||||
binding: 0,
|
binding: 0,
|
||||||
visibility: ShaderStage::VERTEX | ShaderStage::FRAGMENT,
|
visibility: ShaderStages::VERTEX | ShaderStages::FRAGMENT,
|
||||||
ty: BindingType::Buffer {
|
ty: BindingType::Buffer {
|
||||||
ty: BufferBindingType::Uniform,
|
ty: BufferBindingType::Uniform,
|
||||||
has_dynamic_offset: true,
|
has_dynamic_offset: true,
|
||||||
|
@ -56,7 +56,7 @@ impl FromWorld for SpriteShaders {
|
||||||
entries: &[
|
entries: &[
|
||||||
BindGroupLayoutEntry {
|
BindGroupLayoutEntry {
|
||||||
binding: 0,
|
binding: 0,
|
||||||
visibility: ShaderStage::FRAGMENT,
|
visibility: ShaderStages::FRAGMENT,
|
||||||
ty: BindingType::Texture {
|
ty: BindingType::Texture {
|
||||||
multisampled: false,
|
multisampled: false,
|
||||||
sample_type: TextureSampleType::Float { filterable: false },
|
sample_type: TextureSampleType::Float { filterable: false },
|
||||||
|
@ -66,7 +66,7 @@ impl FromWorld for SpriteShaders {
|
||||||
},
|
},
|
||||||
BindGroupLayoutEntry {
|
BindGroupLayoutEntry {
|
||||||
binding: 1,
|
binding: 1,
|
||||||
visibility: ShaderStage::FRAGMENT,
|
visibility: ShaderStages::FRAGMENT,
|
||||||
ty: BindingType::Sampler {
|
ty: BindingType::Sampler {
|
||||||
comparison: false,
|
comparison: false,
|
||||||
filtering: true,
|
filtering: true,
|
||||||
|
@ -89,7 +89,7 @@ impl FromWorld for SpriteShaders {
|
||||||
vertex: VertexState {
|
vertex: VertexState {
|
||||||
buffers: &[VertexBufferLayout {
|
buffers: &[VertexBufferLayout {
|
||||||
array_stride: 20,
|
array_stride: 20,
|
||||||
step_mode: InputStepMode::Vertex,
|
step_mode: VertexStepMode::Vertex,
|
||||||
attributes: &[
|
attributes: &[
|
||||||
VertexAttribute {
|
VertexAttribute {
|
||||||
format: VertexFormat::Float32x3,
|
format: VertexFormat::Float32x3,
|
||||||
|
@ -123,7 +123,7 @@ impl FromWorld for SpriteShaders {
|
||||||
operation: BlendOperation::Add,
|
operation: BlendOperation::Add,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
write_mask: ColorWrite::ALL,
|
write_mask: ColorWrites::ALL,
|
||||||
}],
|
}],
|
||||||
}),
|
}),
|
||||||
layout: Some(&pipeline_layout),
|
layout: Some(&pipeline_layout),
|
||||||
|
@ -231,8 +231,8 @@ pub struct SpriteMeta {
|
||||||
impl Default for SpriteMeta {
|
impl Default for SpriteMeta {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
vertices: BufferVec::new(BufferUsage::VERTEX),
|
vertices: BufferVec::new(BufferUsages::VERTEX),
|
||||||
indices: BufferVec::new(BufferUsage::INDEX),
|
indices: BufferVec::new(BufferUsages::INDEX),
|
||||||
view_bind_group: None,
|
view_bind_group: None,
|
||||||
quad: Quad {
|
quad: Quad {
|
||||||
size: Vec2::new(1.0, 1.0),
|
size: Vec2::new(1.0, 1.0),
|
||||||
|
|
|
@ -4,7 +4,7 @@ struct View {
|
||||||
world_position: vec3<f32>;
|
world_position: vec3<f32>;
|
||||||
};
|
};
|
||||||
[[group(0), binding(0)]]
|
[[group(0), binding(0)]]
|
||||||
var view: View;
|
var<uniform> view: View;
|
||||||
|
|
||||||
struct VertexOutput {
|
struct VertexOutput {
|
||||||
[[location(0)]] uv: vec2<f32>;
|
[[location(0)]] uv: vec2<f32>;
|
||||||
|
|
Loading…
Reference in a new issue