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

Fix some browsers failing due to 8k texture requirement, pick always highest available now #2409

Merged
merged 3 commits into from
Jun 13, 2023
Merged
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
8 changes: 4 additions & 4 deletions crates/re_renderer/examples/framework.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use anyhow::Context as _;
use web_time::Instant;

use re_renderer::{
config::{supported_backends, HardwareTier, RenderContextConfig},
config::{supported_backends, DeviceCaps, RenderContextConfig},
view_builder::ViewBuilder,
RenderContext,
};
Expand Down Expand Up @@ -125,8 +125,8 @@ impl<E: Example + 'static> Application<E> {
.await
.context("failed to find an appropriate adapter")?;

let hardware_tier = HardwareTier::from_adapter(&adapter);
hardware_tier.check_downlevel_capabilities(&adapter.get_downlevel_capabilities())?;
let device_caps = DeviceCaps::from_adapter(&adapter);
device_caps.check_downlevel_capabilities(&adapter.get_downlevel_capabilities())?;
let (device, queue) = adapter
.request_device(
&wgpu::DeviceDescriptor {
Expand Down Expand Up @@ -164,7 +164,7 @@ impl<E: Example + 'static> Application<E> {
queue,
RenderContextConfig {
output_format_color: swapchain_format,
hardware_tier,
device_caps,
},
);

Expand Down
10 changes: 5 additions & 5 deletions crates/re_renderer/shader/global_bindings.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ struct FrameUniformBuffer {
// Size used for all line radii given with Size::AUTO.
auto_size_lines: f32,

/// re_renderer defined hardware tier.
hardware_tier: u32,
/// re_renderer defined device tier.
device_tier: u32,
};

@group(0) @binding(0)
Expand All @@ -41,6 +41,6 @@ var nearest_sampler: sampler;
@group(0) @binding(2)
var trilinear_sampler: sampler;

// See config.rs#HardwareTier
const HARDWARE_TIER_GLES = 0u;
const HARDWARE_TIER_WEBGPU = 1u;
// See config.rs#DeviceTier
const DEVICE_TIER_GLES = 0u;
const DEVICE_TIER_WEBGPU = 1u;
2 changes: 1 addition & 1 deletion crates/re_renderer/shader/utils/depth_offset.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ fn apply_depth_offset(position: Vec4, offset: f32) -> Vec4 {
// How do we get there? We let large depth offset lead to a smaller divisor (w_proj):

var w_scale_bias = f32eps * offset;
if frame.hardware_tier == HARDWARE_TIER_GLES {
if frame.device_tier == DEVICE_TIER_GLES {
// Empirically determined, see section on GLES above.
w_scale_bias *= 1000.0;
}
Expand Down
92 changes: 53 additions & 39 deletions crates/re_renderer/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// Hardware tiers `re_renderer` distinguishes.
/// Device tiers `re_renderer` distinguishes.
///
/// To reduce complexity, we don't do fine-grained feature checks,
/// To reduce complexity, we rarely do fine-grained feature checks,
/// but instead support set of features, each a superset of the next.
///
/// Tiers are sorted from lowest to highest. Certain tiers may not be possible on a given machine/setup,
Expand All @@ -10,7 +10,7 @@
///
/// See also `global_bindings.wgsl`
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum HardwareTier {
pub enum DeviceTier {
/// Limited feature support as provided by WebGL and native GLES2/OpenGL3(ish).
Gles = 0,

Expand All @@ -23,58 +23,74 @@ pub enum HardwareTier {
//HighEnd
}

impl HardwareTier {
/// Whether the current hardware tier supports sampling from textures with a sample count higher than 1.
/// Capabilities of a given device.
///
/// Generally, this is a higher level interpretation of [`wgpu::Limits`].
///
/// We're trying to keep the number of fields in this struct to a minimum and associate
/// as many as possible capabilities with the device tier.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct DeviceCaps {
pub tier: DeviceTier,

/// Maximum texture dimension in pixels in both width and height.
///
/// Since this has a direct effect on the image sizes & screen resolution a user can use, we always pick the highest possible.
pub max_texture_dimension2d: u32,
}

impl DeviceCaps {
/// Whether the current device tier supports sampling from textures with a sample count higher than 1.
pub fn support_sampling_msaa_texture(&self) -> bool {
match self {
HardwareTier::Gles => false,
HardwareTier::FullWebGpuSupport => true,
match self.tier {
DeviceTier::Gles => false,
DeviceTier::FullWebGpuSupport => true,
}
}

/// Whether the current hardware tier supports sampling from textures with a sample count higher than 1.
/// Whether the current device tier supports sampling from textures with a sample count higher than 1.
pub fn support_depth_readback(&self) -> bool {
match self {
HardwareTier::Gles => false,
HardwareTier::FullWebGpuSupport => true,
match self.tier {
DeviceTier::Gles => false,
DeviceTier::FullWebGpuSupport => true,
}
}
}

impl HardwareTier {
/// Picks the highest possible tier for a given adapter.
///
/// Note that it is always possible to pick a lower tier!
pub fn from_adapter(adapter: &wgpu::Adapter) -> Self {
match adapter.get_info().backend {
let tier = match adapter.get_info().backend {
wgpu::Backend::Vulkan
| wgpu::Backend::Metal
| wgpu::Backend::Dx12
| wgpu::Backend::BrowserWebGpu => HardwareTier::FullWebGpuSupport,
| wgpu::Backend::BrowserWebGpu => DeviceTier::FullWebGpuSupport,

// Dx11 support in wgpu is sporadic, treat it like GLES to be on the safe side.
wgpu::Backend::Dx11 | wgpu::Backend::Gl | wgpu::Backend::Empty => HardwareTier::Gles,
wgpu::Backend::Dx11 | wgpu::Backend::Gl | wgpu::Backend::Empty => DeviceTier::Gles,
};

Self {
tier,
max_texture_dimension2d: adapter.limits().max_texture_dimension_2d,
}
}

/// Wgpu limits required by the given hardware tier.
pub fn limits(self) -> wgpu::Limits {
/// Wgpu limits required by the given device tier.
pub fn limits(&self) -> wgpu::Limits {
wgpu::Limits {
// In any scenario require high texture resolution to facilitate rendering into large surfaces
// (important for 4k screens and beyond)
// 8192 is widely supported by now.
max_texture_dimension_2d: 8192,
max_texture_dimension_2d: self.max_texture_dimension2d,
..wgpu::Limits::downlevel_webgl2_defaults()
}
}

/// Required features for the given hardware tier.
pub fn features(self) -> wgpu::Features {
/// Required features for the given device tier.
pub fn features(&self) -> wgpu::Features {
wgpu::Features::empty()
}

/// Device descriptor compatible with the given hardware tier.
pub fn device_descriptor(self) -> wgpu::DeviceDescriptor<'static> {
/// Device descriptor compatible with the given device tier.
pub fn device_descriptor(&self) -> wgpu::DeviceDescriptor<'static> {
wgpu::DeviceDescriptor {
label: Some("re_renderer device"),
features: self.features(),
Expand All @@ -83,36 +99,36 @@ impl HardwareTier {
}

/// Downlevel features required by the given tier.
pub fn required_downlevel_capabilities(self) -> wgpu::DownlevelCapabilities {
pub fn required_downlevel_capabilities(&self) -> wgpu::DownlevelCapabilities {
wgpu::DownlevelCapabilities {
flags: match self {
HardwareTier::Gles => wgpu::DownlevelFlags::empty(),
flags: match self.tier {
DeviceTier::Gles => wgpu::DownlevelFlags::empty(),
// Require fully WebGPU compliance for the native tier.
HardwareTier::FullWebGpuSupport => wgpu::DownlevelFlags::all(),
DeviceTier::FullWebGpuSupport => wgpu::DownlevelFlags::all(),
},
limits: Default::default(), // unused so far both here and in wgpu
shader_model: wgpu::ShaderModel::Sm4,
}
}

/// Checks if passed downlevel capabilities support the given hardware tier.
/// Checks if passed downlevel capabilities support the given device tier.
pub fn check_downlevel_capabilities(
self,
&self,
downlevel_capabilities: &wgpu::DownlevelCapabilities,
) -> anyhow::Result<()> {
let required_downlevel_capabilities = self.required_downlevel_capabilities();
anyhow::ensure!(
downlevel_capabilities.shader_model >= required_downlevel_capabilities.shader_model,
"Adapter does not support the minimum shader model required to run re_renderer at the {:?} tier: {:?}",
self,
self.tier,
required_downlevel_capabilities.shader_model
);
anyhow::ensure!(
downlevel_capabilities
.flags
.contains(required_downlevel_capabilities.flags),
"Adapter does not support the downlevel capabilities required to run re_renderer at the {:?} tier: {:?}",
self,
self.tier,
required_downlevel_capabilities.flags - downlevel_capabilities.flags
);

Expand All @@ -128,10 +144,8 @@ pub struct RenderContextConfig {
/// The color format used by the eframe output buffer.
pub output_format_color: wgpu::TextureFormat,

/// The targeted hardware tier.
///
/// Passed devices are expected to fulfill all restrictions on the provided tier.
pub hardware_tier: HardwareTier,
/// Hardware capabilities of the device.
pub device_caps: DeviceCaps,
}

/// Backends that are officially supported by `re_renderer`.
Expand Down
28 changes: 14 additions & 14 deletions crates/re_renderer/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use type_map::concurrent::{self, TypeMap};

use crate::{
allocator::{CpuWriteGpuReadBelt, GpuReadbackBelt},
config::{HardwareTier, RenderContextConfig},
config::{DeviceTier, RenderContextConfig},
global_bindings::GlobalBindings,
renderer::Renderer,
resource_managers::{MeshManager, TextureManager2D},
Expand Down Expand Up @@ -118,35 +118,35 @@ impl RenderContext {

// Validate capabilities of the device.
assert!(
config.hardware_tier.limits().check_limits(&device.limits()),
"The given device doesn't support the required limits for the given hardware tier {:?}.
config.device_caps.limits().check_limits(&device.limits()),
"The given device doesn't support the required limits for the given hardware caps {:?}.
Required:
{:?}
Actual:
{:?}",
config.hardware_tier,
config.hardware_tier.limits(),
config.device_caps,
config.device_caps.limits(),
device.limits(),
);
assert!(
device.features().contains(config.hardware_tier.features()),
"The given device doesn't support the required features for the given hardware tier {:?}.
device.features().contains(config.device_caps.features()),
"The given device doesn't support the required features for the given hardware caps {:?}.
Required:
{:?}
Actual:
{:?}",
config.hardware_tier,
config.hardware_tier.features(),
config.device_caps,
config.device_caps.features(),
device.features(),
);
assert!(adapter.get_downlevel_capabilities().flags.contains(config.hardware_tier.required_downlevel_capabilities().flags),
"The given device doesn't support the required downlevel capabilities for the given hardware tier {:?}.
assert!(adapter.get_downlevel_capabilities().flags.contains(config.device_caps.required_downlevel_capabilities().flags),
"The given device doesn't support the required downlevel capabilities for the given hardware caps {:?}.
Required:
{:?}
Actual:
{:?}",
config.hardware_tier,
config.hardware_tier.required_downlevel_capabilities(),
config.device_caps,
config.device_caps.required_downlevel_capabilities(),
adapter.get_downlevel_capabilities(),
);

Expand Down Expand Up @@ -249,7 +249,7 @@ impl RenderContext {
//
// For more details check https://github.com/gfx-rs/wgpu/issues/3601
if cfg!(target_arch = "wasm32")
&& self.shared_renderer_data.config.hardware_tier == HardwareTier::Gles
&& self.shared_renderer_data.config.device_caps.tier == DeviceTier::Gles
{
self.device.poll(wgpu::Maintain::Wait);
return;
Expand Down
8 changes: 4 additions & 4 deletions crates/re_renderer/src/draw_phases/outlines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@

use crate::{
allocator::create_and_fill_uniform_buffer_batch,
config::HardwareTier,
config::DeviceCaps,
include_shader_module,
renderer::screen_triangle_vertex_shader,
view_builder::ViewBuilder,
Expand Down Expand Up @@ -177,7 +177,7 @@ impl OutlineMaskProcessor {
const VORONOI_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Rgba16Float;

/// Default MSAA state for the outline mask target.
pub fn mask_default_msaa_state(tier: HardwareTier) -> wgpu::MultisampleState {
pub fn mask_default_msaa_state(tier: &DeviceCaps) -> wgpu::MultisampleState {
wgpu::MultisampleState {
count: Self::mask_sample_count(tier),
mask: !0,
Expand All @@ -186,7 +186,7 @@ impl OutlineMaskProcessor {
}

/// Number of MSAA samples used for the outline mask target.
pub fn mask_sample_count(tier: HardwareTier) -> u32 {
pub fn mask_sample_count(tier: &DeviceCaps) -> u32 {
if tier.support_sampling_msaa_texture() {
// The MSAA shader variant deals with *exactly* 4 samples.
// See `jumpflooding_step_msaa.wgsl`.
Expand All @@ -209,7 +209,7 @@ impl OutlineMaskProcessor {
let texture_pool = &ctx.gpu_resources.textures;

let mask_sample_count =
Self::mask_sample_count(ctx.shared_renderer_data.config.hardware_tier);
Self::mask_sample_count(&ctx.shared_renderer_data.config.device_caps);
let mask_texture_desc = crate::wgpu_resources::TextureDesc {
label: format!("{instance_label}::mask_texture").into(),
size: wgpu::Extent3d {
Expand Down
2 changes: 1 addition & 1 deletion crates/re_renderer/src/draw_phases/picking_layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ impl PickingLayerProcessor {
let direct_depth_readback = ctx
.shared_renderer_data
.config
.hardware_tier
.device_caps
.support_depth_readback();

let picking_depth_target = ctx.gpu_resources.textures.alloc(
Expand Down
4 changes: 2 additions & 2 deletions crates/re_renderer/src/global_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ pub struct FrameUniformBuffer {
// Size used for all line radii given with Size::AUTO.
pub auto_size_lines: f32,

/// re_renderer defined hardware tier.
pub hardware_tier: wgpu_buffer_types::U32RowPadded,
/// re_renderer defined device tier.
pub device_tier: wgpu_buffer_types::U32RowPadded,
}

pub(crate) struct GlobalBindings {
Expand Down
2 changes: 1 addition & 1 deletion crates/re_renderer/src/renderer/depth_cloud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ impl Renderer for DepthCloudRenderer {
depth_stencil: OutlineMaskProcessor::MASK_DEPTH_STATE,
// Alpha to coverage doesn't work with the mask integer target.
multisample: OutlineMaskProcessor::mask_default_msaa_state(
shared_data.config.hardware_tier,
&shared_data.config.device_caps,
),
..render_pipeline_desc_color
},
Expand Down
2 changes: 1 addition & 1 deletion crates/re_renderer/src/renderer/lines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -907,7 +907,7 @@ impl Renderer for LineRenderer {
depth_stencil: OutlineMaskProcessor::MASK_DEPTH_STATE,
// Alpha to coverage doesn't work with the mask integer target.
multisample: OutlineMaskProcessor::mask_default_msaa_state(
shared_data.config.hardware_tier,
&shared_data.config.device_caps,
),
},
&pools.pipeline_layouts,
Expand Down
2 changes: 1 addition & 1 deletion crates/re_renderer/src/renderer/mesh_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ impl Renderer for MeshRenderer {
render_targets: smallvec![Some(OutlineMaskProcessor::MASK_FORMAT.into())],
depth_stencil: OutlineMaskProcessor::MASK_DEPTH_STATE,
multisample: OutlineMaskProcessor::mask_default_msaa_state(
shared_data.config.hardware_tier,
&shared_data.config.device_caps,
),
..render_pipeline_shaded_desc
},
Expand Down
2 changes: 1 addition & 1 deletion crates/re_renderer/src/renderer/point_cloud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,7 @@ impl Renderer for PointCloudRenderer {
depth_stencil: OutlineMaskProcessor::MASK_DEPTH_STATE,
// Alpha to coverage doesn't work with the mask integer target.
multisample: OutlineMaskProcessor::mask_default_msaa_state(
shared_data.config.hardware_tier,
&shared_data.config.device_caps,
),
..render_pipeline_desc_color
},
Expand Down
Loading