Skip to content

Commit

Permalink
Fix some browsers failing due to 8k texture requirement, pick always …
Browse files Browse the repository at this point in the history
…highest available now (#2409)

<!--
Open the PR up as a draft until you feel it is ready for a proper
review.

Do not make PR:s from your own `main` branch, as that makes it difficult
for reviewers to add their own fixes.

Add any improvements to the branch as new commits to make it easier for
reviewers to follow the progress. All commits will be squashed to a
single commit once the PR is merged into `main`.

Make sure you mention any issues that this PR closes in the description,
as well as any other related issues.

To get an auto-generated PR description you can put "copilot:summary" or
"copilot:walkthrough" anywhere.
-->

### What

And rename "hardware tier" to "device tier". Since this breaks the "caps
are a simple enum"-model, there is `DeviceCaps` on top now.

This allows my Mac to ingest 16k textures and my Android mobile phone 4k
textures (Chrome allowed only 4k,Firefox allowed 8k 🤦 )

### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)


<!-- This line will get updated when the PR build summary job finishes.
-->
PR Build Summary: https://build.rerun.io/pr/2409

<!-- pr-link-docs:start -->
Docs preview: https://rerun.io/preview/284b7ec/docs
Examples preview: https://rerun.io/preview/284b7ec/examples
<!-- pr-link-docs:end -->
  • Loading branch information
Wumpf authored and emilk committed Jun 15, 2023
1 parent fd099a2 commit b1e63b5
Show file tree
Hide file tree
Showing 15 changed files with 92 additions and 80 deletions.
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

0 comments on commit b1e63b5

Please sign in to comment.