Skip to content

Commit

Permalink
Enable wgpu device limits (#1544)
Browse files Browse the repository at this point in the history
Follow up on #547 and #1401 

Co-authored-by: Zhixing Zhang <me@neoto.xin>
  • Loading branch information
Neo-Zhixing and Neo-Zhixing committed Mar 3, 2021
1 parent 6a0968b commit 6e14ed2
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 50 deletions.
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,
}
}
}

0 comments on commit 6e14ed2

Please sign in to comment.