diff --git a/crates/bevy_wgpu/src/lib.rs b/crates/bevy_wgpu/src/lib.rs index f7883483f8..2d4156d16f 100644 --- a/crates/bevy_wgpu/src/lib.rs +++ b/crates/bevy_wgpu/src/lib.rs @@ -18,6 +18,79 @@ use bevy_render::{ use futures_lite::future; use renderer::WgpuRenderResourceContext; +#[derive(Clone, Copy)] +pub enum WgpuFeature { + DepthClamping, + TextureCompressionBc, + TimestampQuery, + PipelineStatisticsQuery, + MappablePrimaryBuffers, + SampledTextureBindingArray, + SampledTextureArrayDynamicIndexing, + SampledTextureArrayNonUniformIndexing, + UnsizedBindingArray, + MultiDrawIndirect, + MultiDrawIndirectCount, + PushConstants, + AddressModeClampToBorder, + NonFillPolygonMode, + TextureCompressionEtc2, + TextureCompressionAstcLdr, + TextureAdapterSpecificFormatFeatures, + ShaderFloat64, + VertexAttribute64Bit, +} + +impl From for wgpu::Features { + fn from(value: WgpuFeature) -> Self { + match value { + WgpuFeature::DepthClamping => wgpu::Features::DEPTH_CLAMPING, + WgpuFeature::TextureCompressionBc => wgpu::Features::TEXTURE_COMPRESSION_BC, + WgpuFeature::TimestampQuery => wgpu::Features::TIMESTAMP_QUERY, + WgpuFeature::PipelineStatisticsQuery => wgpu::Features::PIPELINE_STATISTICS_QUERY, + WgpuFeature::MappablePrimaryBuffers => wgpu::Features::MAPPABLE_PRIMARY_BUFFERS, + WgpuFeature::SampledTextureBindingArray => { + wgpu::Features::SAMPLED_TEXTURE_BINDING_ARRAY + } + WgpuFeature::SampledTextureArrayDynamicIndexing => { + wgpu::Features::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING + } + WgpuFeature::SampledTextureArrayNonUniformIndexing => { + wgpu::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING + } + WgpuFeature::UnsizedBindingArray => wgpu::Features::UNSIZED_BINDING_ARRAY, + WgpuFeature::MultiDrawIndirect => wgpu::Features::MULTI_DRAW_INDIRECT, + WgpuFeature::MultiDrawIndirectCount => wgpu::Features::MULTI_DRAW_INDIRECT_COUNT, + WgpuFeature::PushConstants => wgpu::Features::PUSH_CONSTANTS, + WgpuFeature::AddressModeClampToBorder => wgpu::Features::ADDRESS_MODE_CLAMP_TO_BORDER, + WgpuFeature::NonFillPolygonMode => wgpu::Features::NON_FILL_POLYGON_MODE, + WgpuFeature::TextureCompressionEtc2 => wgpu::Features::TEXTURE_COMPRESSION_ETC2, + WgpuFeature::TextureCompressionAstcLdr => wgpu::Features::TEXTURE_COMPRESSION_ASTC_LDR, + WgpuFeature::TextureAdapterSpecificFormatFeatures => { + wgpu::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES + } + WgpuFeature::ShaderFloat64 => wgpu::Features::SHADER_FLOAT64, + WgpuFeature::VertexAttribute64Bit => wgpu::Features::VERTEX_ATTRIBUTE_64BIT, + } + } +} + +impl From for wgpu::Features { + fn from(features: WgpuFeatures) -> Self { + features + .features + .iter() + .fold(wgpu::Features::empty(), |wgpu_features, feature| { + wgpu_features | (*feature).into() + }) + } +} + +#[derive(Default, Clone)] +pub struct WgpuFeatures { + pub features: Vec, +} + #[derive(Default)] pub struct WgpuPlugin; @@ -31,12 +104,12 @@ impl Plugin for WgpuPlugin { ); } } - pub fn get_wgpu_render_system(resources: &mut Resources) -> impl FnMut(&mut World, &mut Resources) { let options = resources .get_cloned::() .unwrap_or_else(WgpuOptions::default); let mut wgpu_renderer = future::block_on(WgpuRenderer::new(options)); + let resource_context = WgpuRenderResourceContext::new(wgpu_renderer.device.clone()); resources.insert::>(Box::new(resource_context)); resources.insert(SharedBuffers::new(4096)); @@ -49,6 +122,7 @@ pub fn get_wgpu_render_system(resources: &mut Resources) -> impl FnMut(&mut Worl pub struct WgpuOptions { pub backend: WgpuBackend, pub power_pref: WgpuPowerOptions, + pub features: WgpuFeatures, } #[derive(Clone)] diff --git a/crates/bevy_wgpu/src/wgpu_renderer.rs b/crates/bevy_wgpu/src/wgpu_renderer.rs index 9bb800c6e3..1491c9894c 100644 --- a/crates/bevy_wgpu/src/wgpu_renderer.rs +++ b/crates/bevy_wgpu/src/wgpu_renderer.rs @@ -54,7 +54,7 @@ impl WgpuRenderer { .request_device( &wgpu::DeviceDescriptor { label: None, - features: wgpu::Features::empty(), + features: options.features.into(), limits: wgpu::Limits::default(), }, trace_path,