Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Enable wgpu device limits #1544

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 36 additions & 44 deletions crates/bevy_wgpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use bevy_render::{
};
use futures_lite::future;
use renderer::WgpuRenderResourceContext;
use std::borrow::Cow;

#[derive(Clone, Copy)]
pub enum WgpuFeature {
Expand All @@ -41,54 +42,43 @@ pub enum WgpuFeature {
VertexAttribute64Bit,
}

impl From<WgpuFeature> 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,
}
}
#[derive(Default, Clone)]
pub struct WgpuFeatures {
pub features: Vec<WgpuFeature>,
}

impl From<WgpuFeatures> for wgpu::Features {
fn from(features: WgpuFeatures) -> Self {
features
.features
.iter()
.fold(wgpu::Features::empty(), |wgpu_features, feature| {
wgpu_features | (*feature).into()
})
}
#[derive(Debug, Clone)]
pub struct WgpuLimits {
pub max_bind_groups: u32,
pub max_dynamic_uniform_buffers_per_pipeline_layout: u32,
pub max_dynamic_storage_buffers_per_pipeline_layout: u32,
pub max_sampled_textures_per_shader_stage: u32,
pub max_samplers_per_shader_stage: u32,
pub max_storage_buffers_per_shader_stage: u32,
pub max_storage_textures_per_shader_stage: u32,
pub max_uniform_buffers_per_shader_stage: u32,
pub max_uniform_buffer_binding_size: u32,
pub max_push_constant_size: u32,
}

#[derive(Default, Clone)]
pub struct WgpuFeatures {
pub features: Vec<WgpuFeature>,
impl Default for WgpuLimits {
fn default() -> Self {
let default = wgpu::Limits::default();
WgpuLimits {
max_bind_groups: default.max_bind_groups,
max_dynamic_uniform_buffers_per_pipeline_layout: default
.max_dynamic_uniform_buffers_per_pipeline_layout,
max_dynamic_storage_buffers_per_pipeline_layout: default
.max_dynamic_storage_buffers_per_pipeline_layout,
max_sampled_textures_per_shader_stage: default.max_sampled_textures_per_shader_stage,
max_samplers_per_shader_stage: default.max_samplers_per_shader_stage,
max_storage_buffers_per_shader_stage: default.max_storage_buffers_per_shader_stage,
max_storage_textures_per_shader_stage: default.max_storage_textures_per_shader_stage,
max_uniform_buffers_per_shader_stage: default.max_uniform_buffers_per_shader_stage,
max_uniform_buffer_binding_size: default.max_uniform_buffer_binding_size,
max_push_constant_size: default.max_push_constant_size,
}
}
}

#[derive(Default)]
Expand Down Expand Up @@ -120,9 +110,11 @@ pub fn get_wgpu_render_system(resources: &mut Resources) -> impl FnMut(&mut Worl

#[derive(Default, Clone)]
pub struct WgpuOptions {
pub device_label: Option<Cow<'static, str>>,
pub backend: WgpuBackend,
pub power_pref: WgpuPowerOptions,
pub features: WgpuFeatures,
pub limits: WgpuLimits,
}

#[derive(Clone)]
Expand Down
8 changes: 5 additions & 3 deletions crates/bevy_wgpu/src/renderer/wgpu_render_resource_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ pub struct WgpuRenderResourceContext {
pub resources: WgpuResources,
}

pub const BIND_BUFFER_ALIGNMENT: usize = 256;
pub const TEXTURE_ALIGNMENT: usize = 256;
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;
pub const COPY_BUFFER_ALIGNMENT: usize = wgpu::COPY_BUFFER_ALIGNMENT as usize;
pub const PUSH_CONSTANT_ALIGNMENT: u32 = wgpu::PUSH_CONSTANT_ALIGNMENT;

impl WgpuRenderResourceContext {
pub fn new(device: Arc<wgpu::Device>) -> Self {
Expand Down Expand Up @@ -657,7 +659,7 @@ impl RenderResourceContext for WgpuRenderResourceContext {
}

fn get_aligned_texture_size(&self, size: usize) -> usize {
(size + TEXTURE_ALIGNMENT - 1) & !(TEXTURE_ALIGNMENT - 1)
(size + COPY_BYTES_PER_ROW_ALIGNMENT - 1) & !(COPY_BYTES_PER_ROW_ALIGNMENT - 1)
}

fn get_aligned_uniform_size(&self, size: usize, dynamic: bool) -> usize {
Expand Down
7 changes: 4 additions & 3 deletions crates/bevy_wgpu/src/wgpu_renderer.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{
renderer::{WgpuRenderGraphExecutor, WgpuRenderResourceContext},
wgpu_type_converter::WgpuInto,
WgpuBackend, WgpuOptions, WgpuPowerOptions,
};
use bevy_app::{prelude::*, ManualEventReader};
Expand Down Expand Up @@ -53,9 +54,9 @@ impl WgpuRenderer {
let (device, queue) = adapter
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: options.features.into(),
limits: wgpu::Limits::default(),
label: options.device_label.as_ref().map(|a| a.as_ref()),
features: options.features.wgpu_into(),
limits: options.limits.wgpu_into(),
},
trace_path,
)
Expand Down
65 changes: 65 additions & 0 deletions crates/bevy_wgpu/src/wgpu_type_converter.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::{WgpuFeature, WgpuFeatures, WgpuLimits};
use bevy_render::{
color::Color,
pass::{LoadOp, Operations},
Expand Down Expand Up @@ -647,3 +648,67 @@ impl WgpuFrom<&Window> for wgpu::SwapChainDescriptor {
}
}
}

impl WgpuFrom<WgpuFeature> 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 WgpuFrom<WgpuFeatures> for wgpu::Features {
fn from(features: WgpuFeatures) -> Self {
features
.features
.iter()
.fold(wgpu::Features::empty(), |wgpu_features, feature| {
wgpu_features | (*feature).wgpu_into()
})
}
}

impl WgpuFrom<WgpuLimits> for wgpu::Limits {
fn from(val: WgpuLimits) -> Self {
wgpu::Limits {
max_bind_groups: val.max_bind_groups,
max_dynamic_uniform_buffers_per_pipeline_layout: val
.max_dynamic_uniform_buffers_per_pipeline_layout,
max_dynamic_storage_buffers_per_pipeline_layout: val
.max_dynamic_storage_buffers_per_pipeline_layout,
max_sampled_textures_per_shader_stage: val.max_sampled_textures_per_shader_stage,
max_samplers_per_shader_stage: val.max_samplers_per_shader_stage,
max_storage_buffers_per_shader_stage: val.max_storage_buffers_per_shader_stage,
max_storage_textures_per_shader_stage: val.max_storage_textures_per_shader_stage,
max_uniform_buffers_per_shader_stage: val.max_uniform_buffers_per_shader_stage,
max_uniform_buffer_binding_size: val.max_uniform_buffer_binding_size,
max_push_constant_size: val.max_push_constant_size,
}
}
}