Upgrade to wgpu v24 (#17542)
Didn't remove WgpuWrapper. Not sure if it's needed or not still. ## Testing - Did you test these changes? If so, how? Example runner - Are there any parts that need more testing? Web (portable atomics thingy?), DXC. ## Migration Guide - Bevy has upgraded to [wgpu v24](https://github.com/gfx-rs/wgpu/blob/trunk/CHANGELOG.md#v2400-2025-01-15). - When using the DirectX 12 rendering backend, the new priority system for choosing a shader compiler is as follows: - If the `WGPU_DX12_COMPILER` environment variable is set at runtime, it is used - Else if the new `statically-linked-dxc` feature is enabled, a custom version of DXC will be statically linked into your app at compile time. - Else Bevy will look in the app's working directory for `dxcompiler.dll` and `dxil.dll` at runtime. - Else if they are missing, Bevy will fall back to FXC (not recommended) --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: IceSentry <c.giguere42@gmail.com> Co-authored-by: François Mockers <francois.mockers@vleue.com>
This commit is contained in:
parent
33e83330eb
commit
669d139c13
@ -256,6 +256,9 @@ bevy_remote = ["bevy_internal/bevy_remote"]
|
||||
# Enable passthrough loading for SPIR-V shaders (Only supported on Vulkan, shader capabilities and extensions must agree with the platform implementation)
|
||||
spirv_shader_passthrough = ["bevy_internal/spirv_shader_passthrough"]
|
||||
|
||||
# Statically linked DXC shader compiler for DirectX 12
|
||||
statically-linked-dxc = ["bevy_internal/statically-linked-dxc"]
|
||||
|
||||
# Tracing support, saving a file in Chrome Tracing format
|
||||
trace_chrome = ["trace", "bevy_internal/trace_chrome"]
|
||||
|
||||
|
@ -22,7 +22,7 @@ serde = { version = "1.0", features = [
|
||||
], default-features = false, optional = true }
|
||||
thiserror = { version = "2", default-features = false }
|
||||
derive_more = { version = "1", default-features = false, features = ["from"] }
|
||||
wgpu-types = { version = "23", default-features = false, optional = true }
|
||||
wgpu-types = { version = "24", default-features = false, optional = true }
|
||||
encase = { version = "0.10", default-features = false, optional = true }
|
||||
|
||||
[features]
|
||||
|
@ -484,6 +484,7 @@ pub fn create_depth_pyramid_dummy_texture(
|
||||
label: Some(texture_view_label),
|
||||
format: Some(TextureFormat::R32Float),
|
||||
dimension: Some(TextureViewDimension::D2),
|
||||
usage: None,
|
||||
aspect: TextureAspect::All,
|
||||
base_mip_level: 0,
|
||||
mip_level_count: Some(1),
|
||||
@ -551,6 +552,7 @@ impl ViewDepthPyramid {
|
||||
label: Some(texture_view_label),
|
||||
format: Some(TextureFormat::R32Float),
|
||||
dimension: Some(TextureViewDimension::D2),
|
||||
usage: None,
|
||||
aspect: TextureAspect::All,
|
||||
base_mip_level: i as u32,
|
||||
mip_level_count: Some(1),
|
||||
|
@ -63,9 +63,7 @@ image = { version = "0.25.2", default-features = false }
|
||||
# misc
|
||||
bitflags = { version = "2.3", features = ["serde"] }
|
||||
bytemuck = { version = "1.5" }
|
||||
wgpu-types = { version = "23", default-features = false }
|
||||
# TODO: remove dependency on wgpu once https://github.com/gfx-rs/wgpu/pull/6648, 6649 and 6650 have been released
|
||||
wgpu = { version = "23.0.1", default-features = false }
|
||||
wgpu-types = { version = "24", default-features = false }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
thiserror = { version = "2", default-features = false }
|
||||
futures-lite = "2.0.1"
|
||||
|
@ -2,8 +2,9 @@
|
||||
|
||||
use ddsfile::{Caps2, D3DFormat, Dds, DxgiFormat};
|
||||
use std::io::Cursor;
|
||||
use wgpu::TextureViewDescriptor;
|
||||
use wgpu_types::{Extent3d, TextureDimension, TextureFormat, TextureViewDimension};
|
||||
use wgpu_types::{
|
||||
Extent3d, TextureDimension, TextureFormat, TextureViewDescriptor, TextureViewDimension,
|
||||
};
|
||||
#[cfg(debug_assertions)]
|
||||
use {bevy_utils::once, tracing::warn};
|
||||
|
||||
@ -283,8 +284,7 @@ pub fn dds_format_to_texture_format(
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use wgpu::util::TextureDataOrder;
|
||||
use wgpu_types::{TextureDescriptor, TextureDimension, TextureFormat};
|
||||
use wgpu_types::{TextureDataOrder, TextureDescriptor, TextureDimension, TextureFormat};
|
||||
|
||||
use crate::CompressedImageFormats;
|
||||
|
||||
|
@ -13,10 +13,10 @@ use bevy_math::{AspectRatio, UVec2, UVec3, Vec2};
|
||||
use core::hash::Hash;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
use wgpu::{SamplerDescriptor, TextureViewDescriptor};
|
||||
use wgpu_types::{
|
||||
AddressMode, CompareFunction, Extent3d, Features, FilterMode, SamplerBorderColor,
|
||||
TextureDescriptor, TextureDimension, TextureFormat, TextureUsages,
|
||||
SamplerDescriptor, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages,
|
||||
TextureViewDescriptor,
|
||||
};
|
||||
|
||||
pub trait BevyDefault {
|
||||
@ -343,7 +343,7 @@ pub struct Image {
|
||||
pub texture_descriptor: TextureDescriptor<Option<&'static str>, &'static [TextureFormat]>,
|
||||
/// The [`ImageSampler`] to use during rendering.
|
||||
pub sampler: ImageSampler,
|
||||
pub texture_view_descriptor: Option<TextureViewDescriptor<'static>>,
|
||||
pub texture_view_descriptor: Option<TextureViewDescriptor<Option<&'static str>>>,
|
||||
pub asset_usage: RenderAssetUsages,
|
||||
}
|
||||
|
||||
@ -559,7 +559,7 @@ impl ImageSamplerDescriptor {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_wgpu(&self) -> SamplerDescriptor {
|
||||
pub fn as_wgpu(&self) -> SamplerDescriptor<Option<&str>> {
|
||||
SamplerDescriptor {
|
||||
label: self.label.as_deref(),
|
||||
address_mode_u: self.address_mode_u.into(),
|
||||
@ -669,8 +669,8 @@ impl From<SamplerBorderColor> for ImageSamplerBorderColor {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<SamplerDescriptor<'a>> for ImageSamplerDescriptor {
|
||||
fn from(value: SamplerDescriptor) -> Self {
|
||||
impl From<SamplerDescriptor<Option<&str>>> for ImageSamplerDescriptor {
|
||||
fn from(value: SamplerDescriptor<Option<&str>>) -> Self {
|
||||
ImageSamplerDescriptor {
|
||||
label: value.label.map(ToString::to_string),
|
||||
address_mode_u: value.address_mode_u.into(),
|
||||
|
@ -13,9 +13,9 @@ use ktx2::{
|
||||
BasicDataFormatDescriptor, ChannelTypeQualifiers, ColorModel, DataFormatDescriptorHeader,
|
||||
Header, SampleInformation,
|
||||
};
|
||||
use wgpu::TextureViewDescriptor;
|
||||
use wgpu_types::{
|
||||
AstcBlock, AstcChannel, Extent3d, TextureDimension, TextureFormat, TextureViewDimension,
|
||||
AstcBlock, AstcChannel, Extent3d, TextureDimension, TextureFormat, TextureViewDescriptor,
|
||||
TextureViewDimension,
|
||||
};
|
||||
|
||||
use super::{CompressedImageFormats, DataFormat, Image, TextureError, TranscodeFormat};
|
||||
|
@ -59,6 +59,10 @@ webp = ["bevy_image/webp"]
|
||||
# Enable SPIR-V passthrough
|
||||
spirv_shader_passthrough = ["bevy_render/spirv_shader_passthrough"]
|
||||
|
||||
# Statically linked DXC shader compiler for DirectX 12
|
||||
# TODO: When wgpu switches to DirectX 12 instead of Vulkan by default on windows, make this a default feature
|
||||
statically-linked-dxc = ["bevy_render/statically-linked-dxc"]
|
||||
|
||||
# Include tonemapping LUT KTX2 files.
|
||||
tonemapping_luts = ["bevy_core_pipeline/tonemapping_luts"]
|
||||
|
||||
|
@ -29,7 +29,7 @@ bevy_platform_support = { path = "../bevy_platform_support", version = "0.16.0-d
|
||||
# other
|
||||
bitflags = { version = "2.3", features = ["serde"] }
|
||||
bytemuck = { version = "1.5" }
|
||||
wgpu-types = { version = "23", default-features = false }
|
||||
wgpu-types = { version = "24", default-features = false }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
hexasphere = "15.0"
|
||||
thiserror = { version = "2", default-features = false }
|
||||
|
@ -6,7 +6,6 @@ use super::{
|
||||
GenerateTangentsError, Indices, MeshAttributeData, MeshTrianglesError, MeshVertexAttribute,
|
||||
MeshVertexAttributeId, MeshVertexBufferLayout, MeshVertexBufferLayoutRef,
|
||||
MeshVertexBufferLayouts, MeshWindingInvertError, VertexAttributeValues, VertexBufferLayout,
|
||||
VertexFormatSize,
|
||||
};
|
||||
use alloc::collections::BTreeMap;
|
||||
use bevy_asset::{Asset, Handle, RenderAssetUsages};
|
||||
@ -379,7 +378,7 @@ impl Mesh {
|
||||
pub fn get_vertex_size(&self) -> u64 {
|
||||
self.attributes
|
||||
.values()
|
||||
.map(|data| data.attribute.format.get_size())
|
||||
.map(|data| data.attribute.format.size())
|
||||
.sum()
|
||||
}
|
||||
|
||||
@ -414,7 +413,7 @@ impl Mesh {
|
||||
format: data.attribute.format,
|
||||
shader_location: index as u32,
|
||||
});
|
||||
accumulated_offset += data.attribute.format.get_size();
|
||||
accumulated_offset += data.attribute.format.size();
|
||||
}
|
||||
|
||||
let layout = MeshVertexBufferLayout {
|
||||
@ -482,7 +481,7 @@ impl Mesh {
|
||||
// bundle into interleaved buffers
|
||||
let mut attribute_offset = 0;
|
||||
for attribute_data in self.attributes.values() {
|
||||
let attribute_size = attribute_data.attribute.format.get_size() as usize;
|
||||
let attribute_size = attribute_data.attribute.format.size() as usize;
|
||||
let attributes_bytes = attribute_data.values.get_bytes();
|
||||
for (vertex_index, attribute_bytes) in attributes_bytes
|
||||
.chunks_exact(attribute_size)
|
||||
|
@ -165,51 +165,6 @@ pub fn face_normal(a: [f32; 3], b: [f32; 3], c: [f32; 3]) -> [f32; 3] {
|
||||
(b - a).cross(c - a).normalize().into()
|
||||
}
|
||||
|
||||
pub trait VertexFormatSize {
|
||||
fn get_size(self) -> u64;
|
||||
}
|
||||
|
||||
impl VertexFormatSize for VertexFormat {
|
||||
fn get_size(self) -> u64 {
|
||||
use core::mem::size_of;
|
||||
let size = match self {
|
||||
VertexFormat::Uint8x2 | VertexFormat::Unorm8x2 => size_of::<u8>() * 2,
|
||||
VertexFormat::Uint8x4 | VertexFormat::Unorm8x4 => size_of::<u8>() * 4,
|
||||
VertexFormat::Sint8x2 | VertexFormat::Snorm8x2 => size_of::<i8>() * 2,
|
||||
VertexFormat::Sint8x4 | VertexFormat::Snorm8x4 => size_of::<i8>() * 4,
|
||||
VertexFormat::Unorm10_10_10_2 => 10 + 10 + 10 + 2,
|
||||
VertexFormat::Uint16x2 | VertexFormat::Unorm16x2 => size_of::<u16>() * 2,
|
||||
VertexFormat::Uint16x4 | VertexFormat::Unorm16x4 => size_of::<u16>() * 4,
|
||||
VertexFormat::Sint16x2 | VertexFormat::Snorm16x2 => size_of::<i16>() * 2,
|
||||
VertexFormat::Sint16x4 | VertexFormat::Snorm16x4 => size_of::<i16>() * 4,
|
||||
// NOTE: As of the time of writing this code, `f16` is not a stabilized primitive, so we
|
||||
// can't use `size_of::<f16>()` here.
|
||||
VertexFormat::Float16x2 => 2 * 2,
|
||||
VertexFormat::Float16x4 => 2 * 4,
|
||||
VertexFormat::Float32 => size_of::<f32>(),
|
||||
VertexFormat::Float32x2 => size_of::<f32>() * 2,
|
||||
VertexFormat::Float32x3 => size_of::<f32>() * 3,
|
||||
VertexFormat::Float32x4 => size_of::<f32>() * 4,
|
||||
VertexFormat::Uint32 => size_of::<u32>(),
|
||||
VertexFormat::Uint32x2 => size_of::<u32>() * 2,
|
||||
VertexFormat::Uint32x3 => size_of::<u32>() * 3,
|
||||
VertexFormat::Uint32x4 => size_of::<u32>() * 4,
|
||||
VertexFormat::Sint32 => size_of::<i32>(),
|
||||
VertexFormat::Sint32x2 => size_of::<i32>() * 2,
|
||||
VertexFormat::Sint32x3 => size_of::<i32>() * 3,
|
||||
VertexFormat::Sint32x4 => size_of::<i32>() * 4,
|
||||
VertexFormat::Float64 => size_of::<f64>(),
|
||||
VertexFormat::Float64x2 => size_of::<f64>() * 2,
|
||||
VertexFormat::Float64x3 => size_of::<f64>() * 3,
|
||||
VertexFormat::Float64x4 => size_of::<f64>() * 4,
|
||||
};
|
||||
|
||||
// We can safely cast `size` (a `usize`) into a `u64`, as we don't even reach the limits of
|
||||
// of a `u8`.
|
||||
size.try_into().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
/// Contains an array where each entry describes a property of a single vertex.
|
||||
/// Matches the [`VertexFormats`](VertexFormat).
|
||||
#[derive(Clone, Debug, EnumVariantMeta)]
|
||||
|
@ -56,8 +56,7 @@ use self::{
|
||||
},
|
||||
visibility_buffer_raster_node::MeshletVisibilityBufferRasterPassNode,
|
||||
};
|
||||
use crate::graph::NodePbr;
|
||||
use crate::PreviousGlobalTransform;
|
||||
use crate::{graph::NodePbr, PreviousGlobalTransform};
|
||||
use bevy_app::{App, Plugin};
|
||||
use bevy_asset::{load_internal_asset, weak_handle, AssetApp, AssetId, Handle};
|
||||
use bevy_core_pipeline::{
|
||||
|
@ -150,7 +150,7 @@ impl Node for MeshletVisibilityBufferRasterPassNode {
|
||||
meshlet_view_resources.raster_cluster_rightmost_slot,
|
||||
);
|
||||
meshlet_view_resources.depth_pyramid.downsample_depth(
|
||||
"meshlet early downsample depth",
|
||||
"downsample_depth",
|
||||
render_context,
|
||||
meshlet_view_resources.view_size,
|
||||
&meshlet_view_bind_groups.downsample_depth,
|
||||
@ -202,7 +202,7 @@ impl Node for MeshletVisibilityBufferRasterPassNode {
|
||||
camera,
|
||||
);
|
||||
meshlet_view_resources.depth_pyramid.downsample_depth(
|
||||
"meshlet late downsample depth",
|
||||
"downsample_depth",
|
||||
render_context,
|
||||
meshlet_view_resources.view_size,
|
||||
&meshlet_view_bind_groups.downsample_depth,
|
||||
@ -270,7 +270,7 @@ impl Node for MeshletVisibilityBufferRasterPassNode {
|
||||
meshlet_view_resources.raster_cluster_rightmost_slot,
|
||||
);
|
||||
meshlet_view_resources.depth_pyramid.downsample_depth(
|
||||
"meshlet early shadow downsample depth",
|
||||
"downsample_depth",
|
||||
render_context,
|
||||
meshlet_view_resources.view_size,
|
||||
&meshlet_view_bind_groups.downsample_depth,
|
||||
@ -315,7 +315,7 @@ impl Node for MeshletVisibilityBufferRasterPassNode {
|
||||
camera,
|
||||
);
|
||||
meshlet_view_resources.depth_pyramid.downsample_depth(
|
||||
"meshlet late shadow downsample depth",
|
||||
"downsample_depth",
|
||||
render_context,
|
||||
meshlet_view_resources.view_size,
|
||||
&meshlet_view_bind_groups.downsample_depth,
|
||||
|
@ -63,10 +63,8 @@ fn main(@builtin(global_invocation_id) global_invocation_id: vec3<u32>) {
|
||||
// If we aren't using `multi_draw_indirect_count`, we have a 1:1 fixed
|
||||
// assignment of batches to slots in the indirect parameters buffer, so we
|
||||
// can just use the instance index as the index of our indirect parameters.
|
||||
let early_instance_count =
|
||||
atomicLoad(&indirect_parameters_metadata[instance_index].early_instance_count);
|
||||
let late_instance_count =
|
||||
atomicLoad(&indirect_parameters_metadata[instance_index].late_instance_count);
|
||||
let early_instance_count = indirect_parameters_metadata[instance_index].early_instance_count;
|
||||
let late_instance_count = indirect_parameters_metadata[instance_index].late_instance_count;
|
||||
|
||||
// If in the early phase, we draw only the early meshes. If in the late
|
||||
// phase, we draw only the late meshes. If in the main phase, draw all the
|
||||
@ -135,4 +133,4 @@ fn main(@builtin(global_invocation_id) global_invocation_id: vec3<u32>) {
|
||||
indirect_parameters[indirect_parameters_index].vertex_count =
|
||||
current_input[mesh_index].index_count;
|
||||
#endif // INDEXED
|
||||
}
|
||||
}
|
||||
|
@ -1151,7 +1151,7 @@ impl SpecializedComputePipeline for PreprocessPipeline {
|
||||
type Key = PreprocessPipelineKey;
|
||||
|
||||
fn specialize(&self, key: Self::Key) -> ComputePipelineDescriptor {
|
||||
let mut shader_defs = vec![];
|
||||
let mut shader_defs = vec!["WRITE_INDIRECT_PARAMETERS_METADATA".into()];
|
||||
if key.contains(PreprocessPipelineKey::FRUSTUM_CULLING) {
|
||||
shader_defs.push("INDIRECT".into());
|
||||
shader_defs.push("FRUSTUM_CULLING".into());
|
||||
|
@ -1077,6 +1077,7 @@ pub fn prepare_lights(
|
||||
all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu"))
|
||||
))]
|
||||
dimension: Some(TextureViewDimension::Cube),
|
||||
usage: None,
|
||||
aspect: TextureAspect::DepthOnly,
|
||||
base_mip_level: 0,
|
||||
mip_level_count: None,
|
||||
@ -1120,6 +1121,7 @@ pub fn prepare_lights(
|
||||
dimension: Some(TextureViewDimension::D2Array),
|
||||
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
|
||||
dimension: Some(TextureViewDimension::D2),
|
||||
usage: None,
|
||||
aspect: TextureAspect::DepthOnly,
|
||||
base_mip_level: 0,
|
||||
mip_level_count: None,
|
||||
@ -1242,6 +1244,7 @@ pub fn prepare_lights(
|
||||
label: Some("point_light_shadow_map_texture_view"),
|
||||
format: None,
|
||||
dimension: Some(TextureViewDimension::D2),
|
||||
usage: None,
|
||||
aspect: TextureAspect::All,
|
||||
base_mip_level: 0,
|
||||
mip_level_count: None,
|
||||
@ -1343,6 +1346,7 @@ pub fn prepare_lights(
|
||||
label: Some("spot_light_shadow_map_texture_view"),
|
||||
format: None,
|
||||
dimension: Some(TextureViewDimension::D2),
|
||||
usage: None,
|
||||
aspect: TextureAspect::All,
|
||||
base_mip_level: 0,
|
||||
mip_level_count: None,
|
||||
@ -1477,6 +1481,7 @@ pub fn prepare_lights(
|
||||
label: Some("directional_light_shadow_map_array_texture_view"),
|
||||
format: None,
|
||||
dimension: Some(TextureViewDimension::D2),
|
||||
usage: None,
|
||||
aspect: TextureAspect::All,
|
||||
base_mip_level: 0,
|
||||
mip_level_count: None,
|
||||
|
@ -1733,7 +1733,7 @@ impl FromWorld for MeshPipeline {
|
||||
render_queue.write_texture(
|
||||
texture.as_image_copy(),
|
||||
&image.data,
|
||||
ImageDataLayout {
|
||||
TexelCopyBufferLayout {
|
||||
offset: 0,
|
||||
bytes_per_row: Some(image.width() * format_size as u32),
|
||||
rows_per_image: None,
|
||||
|
@ -47,7 +47,7 @@ fn search_for_blockers_in_shadow_map_hardware(
|
||||
view_bindings::directional_shadow_textures,
|
||||
view_bindings::directional_shadow_textures_linear_sampler,
|
||||
light_local,
|
||||
0.0,
|
||||
0u,
|
||||
);
|
||||
#else // NO_ARRAY_TEXTURES_SUPPORT
|
||||
let sampled_depth = textureSampleLevel(
|
||||
@ -55,7 +55,7 @@ fn search_for_blockers_in_shadow_map_hardware(
|
||||
view_bindings::directional_shadow_textures_linear_sampler,
|
||||
light_local,
|
||||
array_index,
|
||||
0.0,
|
||||
0u,
|
||||
);
|
||||
#endif // NO_ARRAY_TEXTURES_SUPPORT
|
||||
return select(vec2(0.0), vec2(sampled_depth, 1.0), sampled_depth >= depth);
|
||||
|
@ -242,9 +242,9 @@ fn depth_raymarch_distance_fn_evaluate(
|
||||
// * The shrink-wrap surface is no longer continuous, so it's possible for rays to miss it.
|
||||
|
||||
let linear_depth =
|
||||
1.0 / textureSampleLevel(depth_prepass_texture, depth_linear_sampler, interp_uv, 0.0);
|
||||
1.0 / textureSampleLevel(depth_prepass_texture, depth_linear_sampler, interp_uv, 0u);
|
||||
let unfiltered_depth =
|
||||
1.0 / textureSampleLevel(depth_prepass_texture, depth_nearest_sampler, interp_uv, 0.0);
|
||||
1.0 / textureSampleLevel(depth_prepass_texture, depth_nearest_sampler, interp_uv, 0u);
|
||||
|
||||
var max_depth: f32;
|
||||
var min_depth: f32;
|
||||
|
@ -116,7 +116,7 @@ uuid = { version = "1.13.1", default-features = false, optional = true, features
|
||||
"serde",
|
||||
] }
|
||||
variadics_please = "1.1"
|
||||
wgpu-types = { version = "23", features = ["serde"], optional = true }
|
||||
wgpu-types = { version = "24", features = ["serde"], optional = true }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
uuid = { version = "1.13.1", default-features = false, features = ["js"] }
|
||||
|
@ -24,6 +24,10 @@ shader_format_spirv = ["wgpu/spirv", "naga/spv-in", "naga/spv-out"]
|
||||
# Enable SPIR-V shader passthrough
|
||||
spirv_shader_passthrough = ["wgpu/spirv"]
|
||||
|
||||
# Statically linked DXC shader compiler for DirectX 12
|
||||
# TODO: When wgpu switches to DirectX 12 instead of Vulkan by default on windows, make this a default feature
|
||||
statically-linked-dxc = ["wgpu/static-dxc"]
|
||||
|
||||
trace = ["profiling"]
|
||||
tracing-tracy = []
|
||||
ci_limits = []
|
||||
@ -70,14 +74,14 @@ codespan-reporting = "0.11.0"
|
||||
# It is enabled for now to avoid having to do a significant overhaul of the renderer just for wasm.
|
||||
# When the 'atomics' feature is enabled `fragile-send-sync-non-atomic` does nothing
|
||||
# and Bevy instead wraps `wgpu` types to verify they are not used off their origin thread.
|
||||
wgpu = { version = "23.0.1", default-features = false, features = [
|
||||
wgpu = { version = "24", default-features = false, features = [
|
||||
"wgsl",
|
||||
"dx12",
|
||||
"metal",
|
||||
"naga-ir",
|
||||
"fragile-send-sync-non-atomic-wasm",
|
||||
] }
|
||||
naga = { version = "23", features = ["wgsl-in"] }
|
||||
naga = { version = "24", features = ["wgsl-in"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
bytemuck = { version = "1.5", features = ["derive", "must_cast"] }
|
||||
downcast-rs = { version = "2", default-features = false, features = ["std"] }
|
||||
@ -101,7 +105,7 @@ fixedbitset = { version = "0.5" }
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
# Omit the `glsl` feature in non-WebAssembly by default.
|
||||
naga_oil = { version = "0.16", default-features = false, features = [
|
||||
naga_oil = { version = "0.17", default-features = false, features = [
|
||||
"test_shader",
|
||||
] }
|
||||
|
||||
@ -109,7 +113,7 @@ naga_oil = { version = "0.16", default-features = false, features = [
|
||||
proptest = "1"
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
naga_oil = "0.16"
|
||||
naga_oil = "0.17"
|
||||
js-sys = "0.3"
|
||||
web-sys = { version = "0.3.67", features = [
|
||||
'Blob',
|
||||
|
@ -975,16 +975,22 @@ impl FromWorld for GpuPreprocessingSupport {
|
||||
crate::get_adreno_model(adapter).is_some_and(|model| model != 720 && model <= 730)
|
||||
}
|
||||
|
||||
let max_supported_mode = if device.limits().max_compute_workgroup_size_x == 0 ||
|
||||
is_non_supported_android_device(adapter)
|
||||
let feature_support = device.features().contains(
|
||||
Features::INDIRECT_FIRST_INSTANCE
|
||||
| Features::MULTI_DRAW_INDIRECT
|
||||
| Features::PUSH_CONSTANTS,
|
||||
);
|
||||
// Depth downsampling for occlusion culling requires 12 textures
|
||||
let limit_support = device.limits().max_storage_textures_per_shader_stage >= 12;
|
||||
let downlevel_support = adapter.get_downlevel_capabilities().flags.contains(
|
||||
DownlevelFlags::VERTEX_AND_INSTANCE_INDEX_RESPECTS_RESPECTIVE_FIRST_VALUE_IN_INDIRECT_DRAW
|
||||
);
|
||||
|
||||
let max_supported_mode = if device.limits().max_compute_workgroup_size_x == 0
|
||||
|| is_non_supported_android_device(adapter)
|
||||
{
|
||||
GpuPreprocessingMode::None
|
||||
} else if !device
|
||||
.features()
|
||||
.contains(Features::INDIRECT_FIRST_INSTANCE | Features::MULTI_DRAW_INDIRECT) ||
|
||||
!adapter.get_downlevel_capabilities().flags.contains(
|
||||
DownlevelFlags::VERTEX_AND_INSTANCE_INDEX_RESPECTS_RESPECTIVE_FIRST_VALUE_IN_INDIRECT_DRAW)
|
||||
{
|
||||
} else if !(feature_support && limit_support && downlevel_support) {
|
||||
GpuPreprocessingMode::PreprocessingOnly
|
||||
} else {
|
||||
GpuPreprocessingMode::Culling
|
||||
|
@ -50,8 +50,13 @@ struct IndirectParametersMetadata {
|
||||
mesh_index: u32,
|
||||
base_output_index: u32,
|
||||
batch_set_index: u32,
|
||||
#ifdef WRITE_INDIRECT_PARAMETERS_METADATA
|
||||
early_instance_count: atomic<u32>,
|
||||
late_instance_count: atomic<u32>,
|
||||
#else
|
||||
early_instance_count: u32,
|
||||
late_instance_count: u32,
|
||||
#endif
|
||||
}
|
||||
|
||||
struct IndirectBatchSet {
|
||||
|
@ -1,7 +1,10 @@
|
||||
use crate::{
|
||||
extract_component::ExtractComponentPlugin,
|
||||
render_asset::RenderAssets,
|
||||
render_resource::{Buffer, BufferUsages, Extent3d, ImageDataLayout, Texture, TextureFormat},
|
||||
render_resource::{
|
||||
Buffer, BufferUsages, CommandEncoder, Extent3d, TexelCopyBufferLayout, Texture,
|
||||
TextureFormat,
|
||||
},
|
||||
renderer::{render_system, RenderDevice},
|
||||
storage::{GpuShaderStorageBuffer, ShaderStorageBuffer},
|
||||
sync_world::MainEntity,
|
||||
@ -28,7 +31,6 @@ use encase::internal::ReadFrom;
|
||||
use encase::private::Reader;
|
||||
use encase::ShaderType;
|
||||
use tracing::warn;
|
||||
use wgpu::CommandEncoder;
|
||||
|
||||
/// A plugin that enables reading back gpu buffers and textures to the cpu.
|
||||
pub struct GpuReadbackPlugin {
|
||||
@ -185,7 +187,7 @@ impl GpuReadbackBufferPool {
|
||||
enum ReadbackSource {
|
||||
Texture {
|
||||
texture: Texture,
|
||||
layout: ImageDataLayout,
|
||||
layout: TexelCopyBufferLayout,
|
||||
size: Extent3d,
|
||||
},
|
||||
Buffer {
|
||||
@ -295,7 +297,7 @@ pub(crate) fn submit_readback_commands(world: &World, command_encoder: &mut Comm
|
||||
} => {
|
||||
command_encoder.copy_texture_to_buffer(
|
||||
texture.as_image_copy(),
|
||||
wgpu::ImageCopyBuffer {
|
||||
wgpu::TexelCopyBufferInfo {
|
||||
buffer: &readback.buffer,
|
||||
layout: *layout,
|
||||
},
|
||||
@ -354,9 +356,9 @@ pub(crate) const fn get_aligned_size(extent: Extent3d, pixel_size: u32) -> u32 {
|
||||
extent.height * align_byte_size(extent.width * pixel_size) * extent.depth_or_array_layers
|
||||
}
|
||||
|
||||
/// Get a [`ImageDataLayout`] aligned such that the image can be copied into a buffer.
|
||||
pub(crate) fn layout_data(extent: Extent3d, format: TextureFormat) -> ImageDataLayout {
|
||||
ImageDataLayout {
|
||||
/// Get a [`TexelCopyBufferLayout`] aligned such that the image can be copied into a buffer.
|
||||
pub(crate) fn layout_data(extent: Extent3d, format: TextureFormat) -> TexelCopyBufferLayout {
|
||||
TexelCopyBufferLayout {
|
||||
bytes_per_row: if extent.height > 1 || extent.depth_or_array_layers > 1 {
|
||||
// 1 = 1 row
|
||||
Some(get_aligned_size(
|
||||
|
@ -295,11 +295,17 @@ impl Plugin for RenderPlugin {
|
||||
.cloned();
|
||||
let settings = render_creation.clone();
|
||||
let async_renderer = async move {
|
||||
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
|
||||
let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor {
|
||||
backends,
|
||||
dx12_shader_compiler: settings.dx12_shader_compiler.clone(),
|
||||
flags: settings.instance_flags,
|
||||
gles_minor_version: settings.gles3_minor_version,
|
||||
backend_options: wgpu::BackendOptions {
|
||||
gl: wgpu::GlBackendOptions {
|
||||
gles_minor_version: settings.gles3_minor_version,
|
||||
},
|
||||
dx12: wgpu::Dx12BackendOptions {
|
||||
shader_compiler: settings.dx12_shader_compiler.clone(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
let surface = primary_window.and_then(|wrapper| {
|
||||
|
@ -196,7 +196,7 @@ impl RenderAsset for RenderMesh {
|
||||
let mut vertex_size = 0;
|
||||
for attribute_data in mesh.attributes() {
|
||||
let vertex_format = attribute_data.0.format;
|
||||
vertex_size += vertex_format.get_size() as usize;
|
||||
vertex_size += vertex_format.size() as usize;
|
||||
}
|
||||
|
||||
let vertex_count = mesh.count_vertices();
|
||||
|
@ -6,7 +6,6 @@ use crate::{
|
||||
renderer::RenderDevice,
|
||||
texture::GpuImage,
|
||||
};
|
||||
use alloc::sync::Arc;
|
||||
use bevy_derive::{Deref, DerefMut};
|
||||
use bevy_ecs::system::{SystemParam, SystemParamItem};
|
||||
pub use bevy_render_macros::AsBindGroup;
|
||||
@ -29,7 +28,7 @@ define_atomic_id!(BindGroupId);
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BindGroup {
|
||||
id: BindGroupId,
|
||||
value: Arc<WgpuWrapper<wgpu::BindGroup>>,
|
||||
value: WgpuWrapper<wgpu::BindGroup>,
|
||||
}
|
||||
|
||||
impl BindGroup {
|
||||
@ -58,7 +57,7 @@ impl From<wgpu::BindGroup> for BindGroup {
|
||||
fn from(value: wgpu::BindGroup) -> Self {
|
||||
BindGroup {
|
||||
id: BindGroupId::new(),
|
||||
value: Arc::new(WgpuWrapper::new(value)),
|
||||
value: WgpuWrapper::new(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::define_atomic_id;
|
||||
use crate::renderer::WgpuWrapper;
|
||||
use alloc::sync::Arc;
|
||||
use core::ops::Deref;
|
||||
|
||||
define_atomic_id!(BindGroupLayoutId);
|
||||
@ -16,7 +15,7 @@ define_atomic_id!(BindGroupLayoutId);
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BindGroupLayout {
|
||||
id: BindGroupLayoutId,
|
||||
value: Arc<WgpuWrapper<wgpu::BindGroupLayout>>,
|
||||
value: WgpuWrapper<wgpu::BindGroupLayout>,
|
||||
}
|
||||
|
||||
impl PartialEq for BindGroupLayout {
|
||||
@ -50,7 +49,7 @@ impl From<wgpu::BindGroupLayout> for BindGroupLayout {
|
||||
fn from(value: wgpu::BindGroupLayout) -> Self {
|
||||
BindGroupLayout {
|
||||
id: BindGroupLayoutId::new(),
|
||||
value: Arc::new(WgpuWrapper::new(value)),
|
||||
value: WgpuWrapper::new(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::define_atomic_id;
|
||||
use crate::renderer::WgpuWrapper;
|
||||
use alloc::sync::Arc;
|
||||
use core::ops::{Bound, Deref, RangeBounds};
|
||||
|
||||
define_atomic_id!(BufferId);
|
||||
@ -8,8 +7,7 @@ define_atomic_id!(BufferId);
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Buffer {
|
||||
id: BufferId,
|
||||
value: Arc<WgpuWrapper<wgpu::Buffer>>,
|
||||
size: wgpu::BufferAddress,
|
||||
value: WgpuWrapper<wgpu::Buffer>,
|
||||
}
|
||||
|
||||
impl Buffer {
|
||||
@ -28,7 +26,7 @@ impl Buffer {
|
||||
let size = match bounds.end_bound() {
|
||||
Bound::Included(&bound) => bound + 1,
|
||||
Bound::Excluded(&bound) => bound,
|
||||
Bound::Unbounded => self.size,
|
||||
Bound::Unbounded => self.value.size(),
|
||||
} - offset;
|
||||
BufferSlice {
|
||||
id: self.id,
|
||||
@ -48,8 +46,7 @@ impl From<wgpu::Buffer> for Buffer {
|
||||
fn from(value: wgpu::Buffer) -> Self {
|
||||
Buffer {
|
||||
id: BufferId::new(),
|
||||
size: value.size(),
|
||||
value: Arc::new(WgpuWrapper::new(value)),
|
||||
value: WgpuWrapper::new(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,8 +43,7 @@ pub use wgpu::{
|
||||
ColorWrites, CommandEncoder, CommandEncoderDescriptor, CompareFunction, ComputePass,
|
||||
ComputePassDescriptor, ComputePipelineDescriptor as RawComputePipelineDescriptor,
|
||||
DepthBiasState, DepthStencilState, DownlevelFlags, Extent3d, Face, Features as WgpuFeatures,
|
||||
FilterMode, FragmentState as RawFragmentState, FrontFace, ImageCopyBuffer, ImageCopyBufferBase,
|
||||
ImageCopyTexture, ImageCopyTextureBase, ImageDataLayout, ImageSubresourceRange, IndexFormat,
|
||||
FilterMode, FragmentState as RawFragmentState, FrontFace, ImageSubresourceRange, IndexFormat,
|
||||
Limits as WgpuLimits, LoadOp, Maintain, MapMode, MultisampleState, Operations, Origin3d,
|
||||
PipelineCompilationOptions, PipelineLayout, PipelineLayoutDescriptor, PolygonMode,
|
||||
PrimitiveState, PrimitiveTopology, PushConstantRange, RenderPassColorAttachment,
|
||||
@ -52,10 +51,11 @@ pub use wgpu::{
|
||||
RenderPipelineDescriptor as RawRenderPipelineDescriptor, Sampler as WgpuSampler,
|
||||
SamplerBindingType, SamplerDescriptor, ShaderModule, ShaderModuleDescriptor, ShaderSource,
|
||||
ShaderStages, StencilFaceState, StencilOperation, StencilState, StorageTextureAccess, StoreOp,
|
||||
TextureAspect, TextureDescriptor, TextureDimension, TextureFormat, TextureSampleType,
|
||||
TextureUsages, TextureView as WgpuTextureView, TextureViewDescriptor, TextureViewDimension,
|
||||
VertexAttribute, VertexBufferLayout as RawVertexBufferLayout, VertexFormat,
|
||||
VertexState as RawVertexState, VertexStepMode, COPY_BUFFER_ALIGNMENT,
|
||||
TexelCopyBufferInfo, TexelCopyBufferLayout, TexelCopyTextureInfo, TextureAspect,
|
||||
TextureDescriptor, TextureDimension, TextureFormat, TextureSampleType, TextureUsages,
|
||||
TextureView as WgpuTextureView, TextureViewDescriptor, TextureViewDimension, VertexAttribute,
|
||||
VertexBufferLayout as RawVertexBufferLayout, VertexFormat, VertexState as RawVertexState,
|
||||
VertexStepMode, COPY_BUFFER_ALIGNMENT,
|
||||
};
|
||||
|
||||
pub use crate::mesh::VertexBufferLayout;
|
||||
|
@ -6,7 +6,6 @@ use crate::{
|
||||
render_resource::{BindGroupLayout, Shader},
|
||||
};
|
||||
use alloc::borrow::Cow;
|
||||
use alloc::sync::Arc;
|
||||
use bevy_asset::Handle;
|
||||
use core::ops::Deref;
|
||||
use wgpu::{
|
||||
@ -22,7 +21,7 @@ define_atomic_id!(RenderPipelineId);
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RenderPipeline {
|
||||
id: RenderPipelineId,
|
||||
value: Arc<WgpuWrapper<wgpu::RenderPipeline>>,
|
||||
value: WgpuWrapper<wgpu::RenderPipeline>,
|
||||
}
|
||||
|
||||
impl RenderPipeline {
|
||||
@ -36,7 +35,7 @@ impl From<wgpu::RenderPipeline> for RenderPipeline {
|
||||
fn from(value: wgpu::RenderPipeline) -> Self {
|
||||
RenderPipeline {
|
||||
id: RenderPipelineId::new(),
|
||||
value: Arc::new(WgpuWrapper::new(value)),
|
||||
value: WgpuWrapper::new(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -59,7 +58,7 @@ define_atomic_id!(ComputePipelineId);
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ComputePipeline {
|
||||
id: ComputePipelineId,
|
||||
value: Arc<WgpuWrapper<wgpu::ComputePipeline>>,
|
||||
value: WgpuWrapper<wgpu::ComputePipeline>,
|
||||
}
|
||||
|
||||
impl ComputePipeline {
|
||||
@ -74,7 +73,7 @@ impl From<wgpu::ComputePipeline> for ComputePipeline {
|
||||
fn from(value: wgpu::ComputePipeline) -> Self {
|
||||
ComputePipeline {
|
||||
id: ComputePipelineId::new(),
|
||||
value: Arc::new(WgpuWrapper::new(value)),
|
||||
value: WgpuWrapper::new(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1069,6 +1069,18 @@ fn get_capabilities(features: Features, downlevel: DownlevelFlags) -> Capabiliti
|
||||
Capabilities::SUBGROUP_VERTEX_STAGE,
|
||||
features.contains(Features::SUBGROUP_VERTEX),
|
||||
);
|
||||
capabilities.set(
|
||||
Capabilities::SHADER_FLOAT32_ATOMIC,
|
||||
features.contains(Features::SHADER_FLOAT32_ATOMIC),
|
||||
);
|
||||
capabilities.set(
|
||||
Capabilities::TEXTURE_ATOMIC,
|
||||
features.contains(Features::TEXTURE_ATOMIC),
|
||||
);
|
||||
capabilities.set(
|
||||
Capabilities::TEXTURE_INT64_ATOMIC,
|
||||
features.contains(Features::TEXTURE_INT64_ATOMIC),
|
||||
);
|
||||
|
||||
capabilities
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::define_atomic_id;
|
||||
use crate::renderer::WgpuWrapper;
|
||||
use alloc::sync::Arc;
|
||||
use bevy_derive::{Deref, DerefMut};
|
||||
use bevy_ecs::resource::Resource;
|
||||
use core::ops::Deref;
|
||||
@ -23,7 +22,7 @@ define_atomic_id!(TextureId);
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Texture {
|
||||
id: TextureId,
|
||||
value: Arc<WgpuWrapper<wgpu::Texture>>,
|
||||
value: WgpuWrapper<wgpu::Texture>,
|
||||
}
|
||||
|
||||
impl Texture {
|
||||
@ -43,7 +42,7 @@ impl From<wgpu::Texture> for Texture {
|
||||
fn from(value: wgpu::Texture) -> Self {
|
||||
Texture {
|
||||
id: TextureId::new(),
|
||||
value: Arc::new(WgpuWrapper::new(value)),
|
||||
value: WgpuWrapper::new(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -63,18 +62,16 @@ define_atomic_id!(TextureViewId);
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TextureView {
|
||||
id: TextureViewId,
|
||||
value: Arc<WgpuWrapper<wgpu::TextureView>>,
|
||||
value: WgpuWrapper<wgpu::TextureView>,
|
||||
}
|
||||
|
||||
pub struct SurfaceTexture {
|
||||
value: Arc<WgpuWrapper<wgpu::SurfaceTexture>>,
|
||||
value: WgpuWrapper<wgpu::SurfaceTexture>,
|
||||
}
|
||||
|
||||
impl SurfaceTexture {
|
||||
pub fn try_unwrap(self) -> Option<wgpu::SurfaceTexture> {
|
||||
Arc::try_unwrap(self.value)
|
||||
.map(WgpuWrapper::into_inner)
|
||||
.ok()
|
||||
pub fn present(self) {
|
||||
self.value.into_inner().present();
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,7 +87,7 @@ impl From<wgpu::TextureView> for TextureView {
|
||||
fn from(value: wgpu::TextureView) -> Self {
|
||||
TextureView {
|
||||
id: TextureViewId::new(),
|
||||
value: Arc::new(WgpuWrapper::new(value)),
|
||||
value: WgpuWrapper::new(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -98,7 +95,7 @@ impl From<wgpu::TextureView> for TextureView {
|
||||
impl From<wgpu::SurfaceTexture> for SurfaceTexture {
|
||||
fn from(value: wgpu::SurfaceTexture) -> Self {
|
||||
SurfaceTexture {
|
||||
value: Arc::new(WgpuWrapper::new(value)),
|
||||
value: WgpuWrapper::new(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -131,7 +128,7 @@ define_atomic_id!(SamplerId);
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Sampler {
|
||||
id: SamplerId,
|
||||
value: Arc<WgpuWrapper<wgpu::Sampler>>,
|
||||
value: WgpuWrapper<wgpu::Sampler>,
|
||||
}
|
||||
|
||||
impl Sampler {
|
||||
@ -146,7 +143,7 @@ impl From<wgpu::Sampler> for Sampler {
|
||||
fn from(value: wgpu::Sampler) -> Self {
|
||||
Sampler {
|
||||
id: SamplerId::new(),
|
||||
value: Arc::new(WgpuWrapper::new(value)),
|
||||
value: WgpuWrapper::new(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,14 +87,12 @@ pub fn render_system(world: &mut World, state: &mut SystemState<Query<Entity, Wi
|
||||
|
||||
let mut windows = world.resource_mut::<ExtractedWindows>();
|
||||
for window in windows.values_mut() {
|
||||
if let Some(wrapped_texture) = window.swap_chain_texture.take() {
|
||||
if let Some(surface_texture) = wrapped_texture.try_unwrap() {
|
||||
// TODO(clean): winit docs recommends calling pre_present_notify before this.
|
||||
// though `present()` doesn't present the frame, it schedules it to be presented
|
||||
// by wgpu.
|
||||
// https://docs.rs/winit/0.29.9/wasm32-unknown-unknown/winit/window/struct.Window.html#method.pre_present_notify
|
||||
surface_texture.present();
|
||||
}
|
||||
if let Some(surface_texture) = window.swap_chain_texture.take() {
|
||||
// TODO(clean): winit docs recommends calling pre_present_notify before this.
|
||||
// though `present()` doesn't present the frame, it schedules it to be presented
|
||||
// by wgpu.
|
||||
// https://docs.rs/winit/0.29.9/wasm32-unknown-unknown/winit/window/struct.Window.html#method.pre_present_notify
|
||||
surface_texture.present();
|
||||
}
|
||||
}
|
||||
|
||||
@ -224,10 +222,8 @@ pub async fn initialize_renderer(
|
||||
// RAY_QUERY and RAY_TRACING_ACCELERATION STRUCTURE will sometimes cause DeviceLost failures on platforms
|
||||
// that report them as supported:
|
||||
// <https://github.com/gfx-rs/wgpu/issues/5488>
|
||||
// WGPU also currently doesn't actually support these features yet, so we should disable
|
||||
// them until they are safe to enable.
|
||||
features -= wgpu::Features::RAY_QUERY;
|
||||
features -= wgpu::Features::RAY_TRACING_ACCELERATION_STRUCTURE;
|
||||
features -= wgpu::Features::EXPERIMENTAL_RAY_QUERY;
|
||||
features -= wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE;
|
||||
|
||||
limits = adapter.limits();
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ use crate::render_resource::{
|
||||
RenderPipeline, Sampler, Texture,
|
||||
};
|
||||
use crate::WgpuWrapper;
|
||||
use alloc::sync::Arc;
|
||||
use bevy_ecs::resource::Resource;
|
||||
use wgpu::{
|
||||
util::DeviceExt, BindGroupDescriptor, BindGroupEntry, BindGroupLayoutDescriptor,
|
||||
@ -14,17 +13,17 @@ use wgpu::{
|
||||
/// This GPU device is responsible for the creation of most rendering and compute resources.
|
||||
#[derive(Resource, Clone)]
|
||||
pub struct RenderDevice {
|
||||
device: Arc<WgpuWrapper<wgpu::Device>>,
|
||||
device: WgpuWrapper<wgpu::Device>,
|
||||
}
|
||||
|
||||
impl From<wgpu::Device> for RenderDevice {
|
||||
fn from(device: wgpu::Device) -> Self {
|
||||
Self::new(Arc::new(WgpuWrapper::new(device)))
|
||||
Self::new(WgpuWrapper::new(device))
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderDevice {
|
||||
pub fn new(device: Arc<WgpuWrapper<wgpu::Device>>) -> Self {
|
||||
pub fn new(device: WgpuWrapper<wgpu::Device>) -> Self {
|
||||
Self { device }
|
||||
}
|
||||
|
||||
|
@ -71,10 +71,10 @@ impl Default for WgpuSettings {
|
||||
Backends::all()
|
||||
};
|
||||
|
||||
let backends = Some(wgpu::util::backend_bits_from_env().unwrap_or(default_backends));
|
||||
let backends = Some(Backends::from_env().unwrap_or(default_backends));
|
||||
|
||||
let power_preference =
|
||||
wgpu::util::power_preference_from_env().unwrap_or(PowerPreference::HighPerformance);
|
||||
PowerPreference::from_env().unwrap_or(PowerPreference::HighPerformance);
|
||||
|
||||
let priority = settings_priority_from_env().unwrap_or(WgpuSettingsPriority::Functionality);
|
||||
|
||||
@ -100,13 +100,27 @@ impl Default for WgpuSettings {
|
||||
limits
|
||||
};
|
||||
|
||||
let dx12_compiler =
|
||||
wgpu::util::dx12_shader_compiler_from_env().unwrap_or(Dx12Compiler::Dxc {
|
||||
dxil_path: None,
|
||||
dxc_path: None,
|
||||
let dx12_shader_compiler =
|
||||
Dx12Compiler::from_env().unwrap_or(if cfg!(feature = "statically-linked-dxc") {
|
||||
Dx12Compiler::StaticDxc
|
||||
} else {
|
||||
let dxc = "dxcompiler.dll";
|
||||
let dxil = "dxil.dll";
|
||||
|
||||
if cfg!(target_os = "windows")
|
||||
&& std::fs::metadata(dxc).is_ok()
|
||||
&& std::fs::metadata(dxil).is_ok()
|
||||
{
|
||||
Dx12Compiler::DynamicDxc {
|
||||
dxc_path: String::from(dxc),
|
||||
dxil_path: String::from(dxil),
|
||||
}
|
||||
} else {
|
||||
Dx12Compiler::Fxc
|
||||
}
|
||||
});
|
||||
|
||||
let gles3_minor_version = wgpu::util::gles_minor_version_from_env().unwrap_or_default();
|
||||
let gles3_minor_version = Gles3MinorVersion::from_env().unwrap_or_default();
|
||||
|
||||
let instance_flags = InstanceFlags::default().with_env();
|
||||
|
||||
@ -119,7 +133,7 @@ impl Default for WgpuSettings {
|
||||
disabled_features: None,
|
||||
limits,
|
||||
constrained_limits: None,
|
||||
dx12_shader_compiler: dx12_compiler,
|
||||
dx12_shader_compiler,
|
||||
gles3_minor_version,
|
||||
instance_flags,
|
||||
memory_hints: MemoryHints::default(),
|
||||
|
@ -593,7 +593,7 @@ fn render_screenshot(
|
||||
};
|
||||
encoder.copy_texture_to_buffer(
|
||||
prepared_state.texture.as_image_copy(),
|
||||
wgpu::ImageCopyBuffer {
|
||||
wgpu::TexelCopyBufferInfo {
|
||||
buffer: &prepared_state.buffer,
|
||||
layout: gpu_readback::layout_data(extent, texture_format),
|
||||
},
|
||||
|
@ -360,7 +360,7 @@ impl FromWorld for Mesh2dPipeline {
|
||||
render_queue.write_texture(
|
||||
texture.as_image_copy(),
|
||||
&image.data,
|
||||
ImageDataLayout {
|
||||
TexelCopyBufferLayout {
|
||||
offset: 0,
|
||||
bytes_per_row: Some(image.width() * format_size as u32),
|
||||
rows_per_image: None,
|
||||
|
@ -103,7 +103,7 @@ impl FromWorld for SpritePipeline {
|
||||
render_queue.write_texture(
|
||||
texture.as_image_copy(),
|
||||
&image.data,
|
||||
ImageDataLayout {
|
||||
TexelCopyBufferLayout {
|
||||
offset: 0,
|
||||
bytes_per_row: Some(image.width() * format_size as u32),
|
||||
rows_per_image: None,
|
||||
|
@ -58,7 +58,7 @@ cfg-if = "1.0"
|
||||
raw-window-handle = "0.6"
|
||||
serde = { version = "1.0", features = ["derive"], optional = true }
|
||||
bytemuck = { version = "1.5", optional = true }
|
||||
wgpu-types = { version = "23", optional = true }
|
||||
wgpu-types = { version = "24", optional = true }
|
||||
accesskit = "0.17"
|
||||
tracing = { version = "0.1", default-features = false, features = ["std"] }
|
||||
|
||||
|
@ -96,6 +96,7 @@ The default feature set enables most of the expected features of a game engine,
|
||||
|shader_format_glsl|Enable support for shaders in GLSL|
|
||||
|shader_format_spirv|Enable support for shaders in SPIR-V|
|
||||
|spirv_shader_passthrough|Enable passthrough loading for SPIR-V shaders (Only supported on Vulkan, shader capabilities and extensions must agree with the platform implementation)|
|
||||
|statically-linked-dxc|Statically linked DXC shader compiler for DirectX 12|
|
||||
|symphonia-aac|AAC audio format support (through symphonia)|
|
||||
|symphonia-all|AAC, FLAC, MP3, MP4, OGG/VORBIS, and WAV audio formats support (through symphonia)|
|
||||
|symphonia-flac|FLAC audio format support (through symphonia)|
|
||||
|
@ -17,8 +17,8 @@ use bevy::{
|
||||
render_asset::{RenderAssetUsages, RenderAssets},
|
||||
render_graph::{self, NodeRunError, RenderGraph, RenderGraphContext, RenderLabel},
|
||||
render_resource::{
|
||||
Buffer, BufferDescriptor, BufferUsages, CommandEncoderDescriptor, Extent3d,
|
||||
ImageCopyBuffer, ImageDataLayout, Maintain, MapMode, TextureDimension, TextureFormat,
|
||||
Buffer, BufferDescriptor, BufferUsages, CommandEncoderDescriptor, Extent3d, Maintain,
|
||||
MapMode, TexelCopyBufferInfo, TexelCopyBufferLayout, TextureDimension, TextureFormat,
|
||||
TextureUsages,
|
||||
},
|
||||
renderer::{RenderContext, RenderDevice, RenderQueue},
|
||||
@ -372,9 +372,9 @@ impl render_graph::Node for ImageCopyDriver {
|
||||
|
||||
encoder.copy_texture_to_buffer(
|
||||
src_image.texture.as_image_copy(),
|
||||
ImageCopyBuffer {
|
||||
TexelCopyBufferInfo {
|
||||
buffer: &image_copier.buffer,
|
||||
layout: ImageDataLayout {
|
||||
layout: TexelCopyBufferLayout {
|
||||
offset: 0,
|
||||
bytes_per_row: Some(
|
||||
std::num::NonZero::<u32>::new(padded_bytes_per_row as u32)
|
||||
|
Loading…
Reference in New Issue
Block a user