Skip to content

Commit

Permalink
gpu: Replace use of wgpu .global_id() with explicitly added IDs.
Browse files Browse the repository at this point in the history
The next release of wgpu will remove `.global_id()`, so we have to stop
using them. It will also add `Eq` implementations, which could perhaps
substitute in some cases, but we usually want to compare resources which
currently exist with the IDs of resources that may be obsolete, so using
`Eq` would mean unnecessarily retaining those obsolete resources, which
is worse than generating our own IDs. So, this commit adds a wrapper
type `Identified` which essentially recreates the wgpu ID system.
  • Loading branch information
kpreid committed Sep 4, 2024
1 parent 1b2ab0c commit 87fb899
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 47 deletions.
2 changes: 2 additions & 0 deletions all-is-cubes-gpu/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ mod debug_lines;
pub(crate) use debug_lines::*;
mod draw_to_texture;
pub(crate) use draw_to_texture::*;
mod id;
pub(crate) use id::*;
mod info;
pub use info::*;
mod msw;
Expand Down
75 changes: 75 additions & 0 deletions all-is-cubes-gpu/src/common/id.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//! DIY replacement for the `wgpu` `.global_id()` functionality which is being removed
//! in `wgpu` version 23.

use std::fmt;
use std::marker::PhantomData;
use std::ops;
use std::sync::atomic::{self, Ordering};
use std::sync::Arc;

/// Adds a globally unique identifier to a value.
///
/// This identifier may be used to compare two values which do not implement [`PartialEq`],
/// or remember their identities without necessarily retaining the values themselves.
#[derive(Clone, Debug)]
pub(crate) struct Identified<T> {
id: Id<T>,
value: T,
}

/// A unique identifier for some [`Identified`] value.
pub(crate) struct Id<T> {
id: u64,
_phantom: PhantomData<Arc<T>>,
}

impl<T> Identified<T> {
/// Wraps the given value and assigns a new unique [`Id`] for it.
pub fn new(value: T) -> Self {
static ID_COUNTER: atomic::AtomicU64 = atomic::AtomicU64::new(0);
let id = ID_COUNTER.fetch_add(1, Ordering::Relaxed);
Self {
id: Id {
id,
_phantom: PhantomData,
},
value,
}
}

pub fn global_id(&self) -> Id<T> {
self.id
}
}

impl<T> ops::Deref for Identified<T> {
type Target = T;
fn deref(&self) -> &T {
&self.value
}
}

impl<T> Eq for Id<T> {}
impl<T> PartialEq for Id<T> {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
impl<T> std::hash::Hash for Id<T> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.id.hash(state);
}
}

impl<T> fmt::Debug for Id<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Id").field(&self.id).finish()
}
}

impl<T> Copy for Id<T> {}
impl<T> Clone for Id<T> {
fn clone(&self) -> Self {
*self
}
}
6 changes: 3 additions & 3 deletions all-is-cubes-gpu/src/in_wgpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use all_is_cubes::util::Executor;

use crate::in_wgpu::raytrace_to_texture::RaytraceToTexture;
use crate::in_wgpu::shaders::Shaders;
use crate::Id;
#[cfg(feature = "rerun")]
use crate::RerunFilter;
use crate::{
Expand Down Expand Up @@ -297,10 +298,9 @@ struct EverythingRenderer<I: time::Instant> {
lines_vertex_count: u32,

/// Pipeline for the color postprocessing + info text layer drawing.
postprocess_render_pipeline: Memo<wgpu::Id<wgpu::ShaderModule>, wgpu::RenderPipeline>,
postprocess_render_pipeline: Memo<Id<wgpu::ShaderModule>, wgpu::RenderPipeline>,
#[allow(clippy::type_complexity)]
postprocess_bind_group:
Memo<(wgpu::Id<wgpu::TextureView>, frame_texture::FbtId), wgpu::BindGroup>,
postprocess_bind_group: Memo<(Id<wgpu::TextureView>, frame_texture::FbtId), wgpu::BindGroup>,
postprocess_bind_group_layout: wgpu::BindGroupLayout,
postprocess_camera_buffer: wgpu::Buffer,

Expand Down
16 changes: 9 additions & 7 deletions all-is-cubes-gpu/src/in_wgpu/block_texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use all_is_cubes_mesh::texture::{self, Channels};
use crate::in_wgpu::glue::{size3d_to_extent, write_texture_by_aab};
use crate::in_wgpu::vertex::{AtlasTexel, FixTexCoord, TexPoint};
use crate::octree_alloc::{Alloctree, AlloctreeHandle};
use crate::{BlockTextureInfo, Msw};
use crate::{BlockTextureInfo, Identified, Msw};

//------------------------------------------------------------------------------------------------//
// Types
Expand Down Expand Up @@ -56,9 +56,9 @@ pub struct AtlasTile {
}

pub(crate) struct BlockTextureViews {
pub g0_reflectance: Arc<wgpu::TextureView>,
pub g1_reflectance: Arc<wgpu::TextureView>,
pub g1_emission: Arc<wgpu::TextureView>,
pub g0_reflectance: Arc<Identified<wgpu::TextureView>>,
pub g1_reflectance: Arc<Identified<wgpu::TextureView>>,
pub g1_emission: Arc<Identified<wgpu::TextureView>>,
}

/// Internal, weak-referencing version of [`AtlasTile`].
Expand Down Expand Up @@ -137,7 +137,7 @@ struct GpuTexture {
texture: wgpu::Texture,
/// The texture view is wrapped in [`Arc`] so that it can be used by drawing code
/// without holding the lock around this.
texture_view: Arc<wgpu::TextureView>,
texture_view: Arc<Identified<wgpu::TextureView>>,
}

//------------------------------------------------------------------------------------------------//
Expand Down Expand Up @@ -298,7 +298,7 @@ impl AllocatorBacking {
backing_mutex: &Mutex<Self>,
device: &wgpu::Device,
queue: &wgpu::Queue,
) -> (Group<Arc<wgpu::TextureView>>, BlockTextureInfo) {
) -> (Group<Arc<Identified<wgpu::TextureView>>>, BlockTextureInfo) {
let mut backing_lock_guard = backing_mutex.lock().unwrap();
let backing = &mut *backing_lock_guard;

Expand Down Expand Up @@ -492,7 +492,9 @@ impl GpuTexture {
| wgpu::TextureUsages::COPY_DST,
label: Some(label),
});
let texture_view = Arc::new(texture.create_view(&wgpu::TextureViewDescriptor::default()));
let texture_view = Arc::new(Identified::new(
texture.create_view(&wgpu::TextureViewDescriptor::default()),
));
Self {
texture,
texture_view,
Expand Down
6 changes: 3 additions & 3 deletions all-is-cubes-gpu/src/in_wgpu/bloom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub(crate) struct BloomPipelines {
linear_sampler: wgpu::Sampler,
downsample_pipeline: wgpu::RenderPipeline,
upsample_pipeline: wgpu::RenderPipeline,
bloom_shader_id: wgpu::Id<wgpu::ShaderModule>,
bloom_shader_id: crate::Id<wgpu::ShaderModule>,
}

impl BloomPipelines {
Expand Down Expand Up @@ -167,7 +167,7 @@ pub(crate) struct BloomResources {

pub bloom_output_texture_view: wgpu::TextureView,

bloom_shader_id: wgpu::Id<wgpu::ShaderModule>,
bloom_shader_id: crate::Id<wgpu::ShaderModule>,
}

impl BloomResources {
Expand Down Expand Up @@ -281,7 +281,7 @@ impl BloomResources {
}

/// For determinig whether this is outdated
pub(crate) fn bloom_shader_id(&self) -> wgpu::Id<wgpu::ShaderModule> {
pub(crate) fn bloom_shader_id(&self) -> crate::Id<wgpu::ShaderModule> {
self.bloom_shader_id
}
}
Expand Down
24 changes: 13 additions & 11 deletions all-is-cubes-gpu/src/in_wgpu/frame_texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ use all_is_cubes_render::Flaws;

use super::bloom;
use crate::in_wgpu::shaders::Shaders;
use crate::EgFramebuffer;
use crate::{EgFramebuffer, Identified};

/// A RGBA [`wgpu::Texture`] with a CPU-side buffer that can be drawn on.
pub(crate) struct DrawableTexture<In, Out> {
texture_format: wgpu::TextureFormat,
texture: Option<wgpu::Texture>,
texture_view: Option<wgpu::TextureView>,
texture_view: Option<Identified<wgpu::TextureView>>,
size: wgpu::Extent3d,
local_buffer: EgFramebuffer<In, Out>,
}
Expand Down Expand Up @@ -72,7 +72,9 @@ impl<In, Out: Copy + Default + bytemuck::Pod> DrawableTexture<In, Out> {
width: new_extent.width,
height: new_extent.height,
}),
texture_view: Some(texture.create_view(&wgpu::TextureViewDescriptor::default())),
texture_view: Some(Identified::new(
texture.create_view(&wgpu::TextureViewDescriptor::default()),
)),
texture: Some(texture),
size: new_extent,
};
Expand All @@ -82,7 +84,7 @@ impl<In, Out: Copy + Default + bytemuck::Pod> DrawableTexture<In, Out> {
&mut self.local_buffer
}

pub fn view(&self) -> Option<&wgpu::TextureView> {
pub fn view(&self) -> Option<&Identified<wgpu::TextureView>> {
self.texture_view.as_ref()
}

Expand Down Expand Up @@ -166,7 +168,7 @@ pub(crate) struct FramebufferTextures {
linear_scene_tex: wgpu::Texture,
/// View for writing into [`Self::linear_scene_texture`], and reading if multisampling
/// is not enabled.
linear_scene_view: wgpu::TextureView,
linear_scene_view: Identified<wgpu::TextureView>,

/// If multisampling is enabled, provides the “resolve target” companion to
/// `linear_scene_texture`. This texture has a `sample_count` of 1, is
Expand All @@ -175,7 +177,7 @@ pub(crate) struct FramebufferTextures {
/// `linear_scene_texture` directly as input to postprocessing.
linear_scene_resolved_tex: Option<wgpu::Texture>,
/// View for reading [`Self::linear_scene_resolved_tex`].
linear_scene_resolved_view: Option<wgpu::TextureView>,
linear_scene_resolved_view: Option<Identified<wgpu::TextureView>>,

/// Depth texture to pair with `linear_scene_texture`.
depth_texture_view: wgpu::TextureView,
Expand Down Expand Up @@ -256,10 +258,10 @@ impl FramebufferTextures {
None
};

let linear_scene_view = linear_scene_tex.create_view(&Default::default());
let linear_scene_view = Identified::new(linear_scene_tex.create_view(&Default::default()));
let linear_scene_resolved_view = linear_scene_resolved_tex
.as_ref()
.map(|t| t.create_view(&Default::default()));
.map(|t| Identified::new(t.create_view(&Default::default())));

// TODO: duplicative with scene_for_postprocessing_input
let bloom_input_view = if let Some(resolved) = &linear_scene_resolved_view {
Expand Down Expand Up @@ -296,7 +298,7 @@ impl FramebufferTextures {
) -> wgpu::RenderPassColorAttachment<'_> {
wgpu::RenderPassColorAttachment {
view: &self.linear_scene_view,
resolve_target: self.linear_scene_resolved_view.as_ref(),
resolve_target: self.linear_scene_resolved_view.as_deref(),
ops: wgpu::Operations {
load: color_load_op,
store: wgpu::StoreOp::Store,
Expand Down Expand Up @@ -324,7 +326,7 @@ impl FramebufferTextures {
stencil_ops: None,
}
}
pub(crate) fn scene_for_postprocessing_input(&self) -> &wgpu::TextureView {
pub(crate) fn scene_for_postprocessing_input(&self) -> &Identified<wgpu::TextureView> {
if let Some(resolved) = &self.linear_scene_resolved_view {
resolved
} else {
Expand Down Expand Up @@ -416,7 +418,7 @@ impl FramebufferTextures {
/// has the same GPU resources or not, for [`common::Memo`] purposes.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) struct FbtId {
scene_id: wgpu::Id<wgpu::TextureView>,
scene_id: crate::Id<wgpu::TextureView>,
}

/// Pure-data inputs to [`FramebufferTextures`]'s choice of texture format and size.
Expand Down
13 changes: 8 additions & 5 deletions all-is-cubes-gpu/src/in_wgpu/light_texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ use all_is_cubes::math::{
use all_is_cubes::space::Space;
use all_is_cubes_render::camera::Camera;

use crate::in_wgpu::glue::{
extent_to_size3d, point_to_origin, size3d_to_extent, write_texture_by_aab,
use crate::{
in_wgpu::glue::{extent_to_size3d, point_to_origin, size3d_to_extent, write_texture_by_aab},
Identified,
};

type Texel = [u8; LightTexture::COMPONENTS];
Expand Down Expand Up @@ -63,7 +64,7 @@ fn visible_light_volume(space_bounds: GridAab, camera: &Camera) -> GridAab {
#[doc(hidden)] // public for benchmark
pub struct LightTexture {
texture: wgpu::Texture,
texture_view: wgpu::TextureView,
texture_view: Identified<wgpu::TextureView>,

/// Temporary storage for updated light texels to be copied into the texture.
copy_buffer: wgpu::Buffer,
Expand Down Expand Up @@ -116,7 +117,9 @@ impl LightTexture {
label: Some(&format!("{label_prefix} space light")),
});
Self {
texture_view: texture.create_view(&wgpu::TextureViewDescriptor::default()),
texture_view: Identified::new(
texture.create_view(&wgpu::TextureViewDescriptor::default()),
),
texture,
copy_buffer: device.create_buffer(&wgpu::BufferDescriptor {
label: Some(&format!("{label_prefix} space light copy buffer")),
Expand Down Expand Up @@ -392,7 +395,7 @@ impl LightTexture {
total_count
}

pub fn texture_view(&self) -> &wgpu::TextureView {
pub(crate) fn texture_view(&self) -> &Identified<wgpu::TextureView> {
&self.texture_view
}
}
Expand Down
6 changes: 3 additions & 3 deletions all-is-cubes-gpu/src/in_wgpu/raytrace_to_texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ use all_is_cubes_render::RenderError;

use crate::in_wgpu::frame_texture::DrawableTexture;
use crate::in_wgpu::pipelines::Pipelines;
use crate::{Memo, ToTexel};
use crate::{Identified, Memo, ToTexel};

#[derive(Debug)]
pub(crate) struct RaytraceToTexture {
inner: Arc<Mutex<Inner>>,
frame_copy_bind_group: Memo<wgpu::Id<wgpu::TextureView>, wgpu::BindGroup>,
frame_copy_bind_group: Memo<crate::Id<wgpu::TextureView>, wgpu::BindGroup>,
}

/// State for the possibly-asynchronous tracing job.
Expand Down Expand Up @@ -102,7 +102,7 @@ impl RaytraceToTexture {
inner.set_viewport(device, raytracer_size_policy(camera.viewport()));

// Update bind group if needed
let rt_texture_view: &wgpu::TextureView = inner.render_target.view().unwrap();
let rt_texture_view: &Identified<wgpu::TextureView> = inner.render_target.view().unwrap();
self.frame_copy_bind_group
.get_or_insert(rt_texture_view.global_id(), || {
device.create_bind_group(&wgpu::BindGroupDescriptor {
Expand Down
2 changes: 1 addition & 1 deletion all-is-cubes-gpu/src/in_wgpu/rerun_image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub(crate) struct RerunImageExport {
/// Intermediate textures used for format conversions.
/// The texture ID is of the scene color texture we need to read.
/// The image size is our intermediate texture size, which may be different.
resources: Memo<(wgpu::Id<wgpu::TextureView>, ImageSize), Resources>,
resources: Memo<(crate::Id<wgpu::TextureView>, ImageSize), Resources>,
}

struct Resources {
Expand Down
Loading

0 comments on commit 87fb899

Please sign in to comment.