Replace UUID based IDs with a atomic-counted ones (#6988)
# Objective - alternative to #2895 - as mentioned in #2535 the uuid based ids in the render module should be replaced with atomic-counted ones ## Solution - instead of generating a random UUID for each render resource, this implementation increases an atomic counter - this might be replaced by the ids of wgpu if they expose them directly in the future - I have not benchmarked this solution yet, but this should be slightly faster in theory. - Bevymark does not seem to be affected much by this change, which is to be expected. - Nothing of our API has changed, other than that the IDs have lost their IMO rather insignificant documentation. - Maybe the documentation could be added back into the macro, but this would complicate the code.
This commit is contained in:
parent
d3d635b64f
commit
965ebeff59
@ -1,4 +1,5 @@
|
||||
use crate::{
|
||||
define_atomic_id,
|
||||
render_graph::{
|
||||
Edge, InputSlotError, OutputSlotError, RenderGraphContext, RenderGraphError,
|
||||
RunSubGraphError, SlotInfo, SlotInfos, SlotType, SlotValue,
|
||||
@ -6,28 +7,11 @@ use crate::{
|
||||
renderer::RenderContext,
|
||||
};
|
||||
use bevy_ecs::world::World;
|
||||
use bevy_utils::Uuid;
|
||||
use downcast_rs::{impl_downcast, Downcast};
|
||||
use std::{borrow::Cow, fmt::Debug};
|
||||
use thiserror::Error;
|
||||
|
||||
/// A [`Node`] identifier.
|
||||
/// It automatically generates its own random uuid.
|
||||
///
|
||||
/// This id is used to reference the node internally (edges, etc).
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
pub struct NodeId(Uuid);
|
||||
|
||||
impl NodeId {
|
||||
#[allow(clippy::new_without_default)]
|
||||
pub fn new() -> Self {
|
||||
NodeId(Uuid::new_v4())
|
||||
}
|
||||
|
||||
pub fn uuid(&self) -> &Uuid {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
define_atomic_id!(NodeId);
|
||||
|
||||
/// A render node that can be added to a [`RenderGraph`](super::RenderGraph).
|
||||
///
|
||||
|
||||
@ -1,24 +1,19 @@
|
||||
pub use bevy_render_macros::AsBindGroup;
|
||||
use encase::ShaderType;
|
||||
|
||||
use crate::{
|
||||
define_atomic_id,
|
||||
prelude::Image,
|
||||
render_asset::RenderAssets,
|
||||
render_resource::{BindGroupLayout, Buffer, Sampler, TextureView},
|
||||
render_resource::{resource_macros::*, BindGroupLayout, Buffer, Sampler, TextureView},
|
||||
renderer::RenderDevice,
|
||||
texture::FallbackImage,
|
||||
};
|
||||
use bevy_reflect::Uuid;
|
||||
pub use bevy_render_macros::AsBindGroup;
|
||||
use encase::ShaderType;
|
||||
use std::ops::Deref;
|
||||
use wgpu::BindingResource;
|
||||
|
||||
use crate::render_resource::resource_macros::*;
|
||||
define_atomic_id!(BindGroupId);
|
||||
render_resource_wrapper!(ErasedBindGroup, wgpu::BindGroup);
|
||||
|
||||
/// A [`BindGroup`] identifier.
|
||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
||||
pub struct BindGroupId(Uuid);
|
||||
|
||||
/// Bind groups are responsible for binding render resources (e.g. buffers, textures, samplers)
|
||||
/// to a [`TrackedRenderPass`](crate::render_phase::TrackedRenderPass).
|
||||
/// This makes them accessible in the pipeline (shaders) as uniforms.
|
||||
@ -42,7 +37,7 @@ impl BindGroup {
|
||||
impl From<wgpu::BindGroup> for BindGroup {
|
||||
fn from(value: wgpu::BindGroup) -> Self {
|
||||
BindGroup {
|
||||
id: BindGroupId(Uuid::new_v4()),
|
||||
id: BindGroupId::new(),
|
||||
value: ErasedBindGroup::new(value),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,7 @@
|
||||
use crate::render_resource::resource_macros::*;
|
||||
use bevy_reflect::Uuid;
|
||||
use crate::{define_atomic_id, render_resource::resource_macros::*};
|
||||
use std::ops::Deref;
|
||||
|
||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
||||
pub struct BindGroupLayoutId(Uuid);
|
||||
|
||||
define_atomic_id!(BindGroupLayoutId);
|
||||
render_resource_wrapper!(ErasedBindGroupLayout, wgpu::BindGroupLayout);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -34,7 +31,7 @@ impl BindGroupLayout {
|
||||
impl From<wgpu::BindGroupLayout> for BindGroupLayout {
|
||||
fn from(value: wgpu::BindGroupLayout) -> Self {
|
||||
BindGroupLayout {
|
||||
id: BindGroupLayoutId(Uuid::new_v4()),
|
||||
id: BindGroupLayoutId::new(),
|
||||
value: ErasedBindGroupLayout::new(value),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,7 @@
|
||||
use bevy_utils::Uuid;
|
||||
use crate::{define_atomic_id, render_resource::resource_macros::render_resource_wrapper};
|
||||
use std::ops::{Bound, Deref, RangeBounds};
|
||||
|
||||
use crate::render_resource::resource_macros::*;
|
||||
|
||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
||||
pub struct BufferId(Uuid);
|
||||
|
||||
define_atomic_id!(BufferId);
|
||||
render_resource_wrapper!(ErasedBuffer, wgpu::Buffer);
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -42,7 +38,7 @@ impl Buffer {
|
||||
impl From<wgpu::Buffer> for Buffer {
|
||||
fn from(value: wgpu::Buffer) -> Self {
|
||||
Buffer {
|
||||
id: BufferId(Uuid::new_v4()),
|
||||
id: BufferId::new(),
|
||||
value: ErasedBuffer::new(value),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,19 +1,16 @@
|
||||
use crate::render_resource::{BindGroupLayout, Shader};
|
||||
use super::ShaderDefVal;
|
||||
use crate::{
|
||||
define_atomic_id,
|
||||
render_resource::{resource_macros::render_resource_wrapper, BindGroupLayout, Shader},
|
||||
};
|
||||
use bevy_asset::Handle;
|
||||
use bevy_reflect::Uuid;
|
||||
use std::{borrow::Cow, ops::Deref};
|
||||
use wgpu::{
|
||||
BufferAddress, ColorTargetState, DepthStencilState, MultisampleState, PrimitiveState,
|
||||
VertexAttribute, VertexFormat, VertexStepMode,
|
||||
};
|
||||
|
||||
use super::ShaderDefVal;
|
||||
use crate::render_resource::resource_macros::*;
|
||||
|
||||
/// A [`RenderPipeline`] identifier.
|
||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
||||
pub struct RenderPipelineId(Uuid);
|
||||
|
||||
define_atomic_id!(RenderPipelineId);
|
||||
render_resource_wrapper!(ErasedRenderPipeline, wgpu::RenderPipeline);
|
||||
|
||||
/// A [`RenderPipeline`] represents a graphics pipeline and its stages (shaders), bindings and vertex buffers.
|
||||
@ -36,7 +33,7 @@ impl RenderPipeline {
|
||||
impl From<wgpu::RenderPipeline> for RenderPipeline {
|
||||
fn from(value: wgpu::RenderPipeline) -> Self {
|
||||
RenderPipeline {
|
||||
id: RenderPipelineId(Uuid::new_v4()),
|
||||
id: RenderPipelineId::new(),
|
||||
value: ErasedRenderPipeline::new(value),
|
||||
}
|
||||
}
|
||||
@ -51,10 +48,7 @@ impl Deref for RenderPipeline {
|
||||
}
|
||||
}
|
||||
|
||||
/// A [`ComputePipeline`] identifier.
|
||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
||||
pub struct ComputePipelineId(Uuid);
|
||||
|
||||
define_atomic_id!(ComputePipelineId);
|
||||
render_resource_wrapper!(ErasedComputePipeline, wgpu::ComputePipeline);
|
||||
|
||||
/// A [`ComputePipeline`] represents a compute pipeline and its single shader stage.
|
||||
@ -78,7 +72,7 @@ impl ComputePipeline {
|
||||
impl From<wgpu::ComputePipeline> for ComputePipeline {
|
||||
fn from(value: wgpu::ComputePipeline) -> Self {
|
||||
ComputePipeline {
|
||||
id: ComputePipelineId(Uuid::new_v4()),
|
||||
id: ComputePipelineId::new(),
|
||||
value: ErasedComputePipeline::new(value),
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,4 +120,32 @@ macro_rules! render_resource_wrapper {
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! define_atomic_id {
|
||||
($atomic_id_type:ident) => {
|
||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
||||
pub struct $atomic_id_type(u32);
|
||||
|
||||
// We use new instead of default to indicate that each ID created will be unique.
|
||||
#[allow(clippy::new_without_default)]
|
||||
impl $atomic_id_type {
|
||||
pub fn new() -> Self {
|
||||
use std::sync::atomic::{AtomicU32, Ordering};
|
||||
|
||||
static COUNTER: AtomicU32 = AtomicU32::new(1);
|
||||
|
||||
match COUNTER.fetch_add(1, Ordering::Relaxed) {
|
||||
0 => {
|
||||
panic!(
|
||||
"The system ran out of unique `{}`s.",
|
||||
stringify!($atomic_id_type)
|
||||
);
|
||||
}
|
||||
id => Self(id),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub use render_resource_wrapper;
|
||||
|
||||
@ -1,27 +1,16 @@
|
||||
use super::ShaderDefVal;
|
||||
use crate::define_atomic_id;
|
||||
use bevy_asset::{AssetLoader, AssetPath, Handle, LoadContext, LoadedAsset};
|
||||
use bevy_reflect::{TypeUuid, Uuid};
|
||||
use bevy_reflect::TypeUuid;
|
||||
use bevy_utils::{tracing::error, BoxedFuture, HashMap};
|
||||
use naga::back::wgsl::WriterFlags;
|
||||
use naga::valid::Capabilities;
|
||||
use naga::{valid::ModuleInfo, Module};
|
||||
use naga::{back::wgsl::WriterFlags, valid::Capabilities, valid::ModuleInfo, Module};
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use std::{borrow::Cow, marker::Copy, ops::Deref, path::PathBuf, str::FromStr};
|
||||
use thiserror::Error;
|
||||
use wgpu::Features;
|
||||
use wgpu::{util::make_spirv, ShaderModuleDescriptor, ShaderSource};
|
||||
use wgpu::{util::make_spirv, Features, ShaderModuleDescriptor, ShaderSource};
|
||||
|
||||
use super::ShaderDefVal;
|
||||
|
||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
||||
pub struct ShaderId(Uuid);
|
||||
|
||||
impl ShaderId {
|
||||
#[allow(clippy::new_without_default)]
|
||||
pub fn new() -> Self {
|
||||
ShaderId(Uuid::new_v4())
|
||||
}
|
||||
}
|
||||
define_atomic_id!(ShaderId);
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum ShaderReflectError {
|
||||
|
||||
@ -1,12 +1,9 @@
|
||||
use bevy_utils::Uuid;
|
||||
use crate::define_atomic_id;
|
||||
use std::ops::Deref;
|
||||
|
||||
use crate::render_resource::resource_macros::*;
|
||||
|
||||
/// A [`Texture`] identifier.
|
||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
||||
pub struct TextureId(Uuid);
|
||||
|
||||
define_atomic_id!(TextureId);
|
||||
render_resource_wrapper!(ErasedTexture, wgpu::Texture);
|
||||
|
||||
/// A GPU-accessible texture.
|
||||
@ -35,7 +32,7 @@ impl Texture {
|
||||
impl From<wgpu::Texture> for Texture {
|
||||
fn from(value: wgpu::Texture) -> Self {
|
||||
Texture {
|
||||
id: TextureId(Uuid::new_v4()),
|
||||
id: TextureId::new(),
|
||||
value: ErasedTexture::new(value),
|
||||
}
|
||||
}
|
||||
@ -50,10 +47,7 @@ impl Deref for Texture {
|
||||
}
|
||||
}
|
||||
|
||||
/// A [`TextureView`] identifier.
|
||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
||||
pub struct TextureViewId(Uuid);
|
||||
|
||||
define_atomic_id!(TextureViewId);
|
||||
render_resource_wrapper!(ErasedTextureView, wgpu::TextureView);
|
||||
render_resource_wrapper!(ErasedSurfaceTexture, wgpu::SurfaceTexture);
|
||||
|
||||
@ -104,7 +98,7 @@ impl TextureView {
|
||||
impl From<wgpu::TextureView> for TextureView {
|
||||
fn from(value: wgpu::TextureView) -> Self {
|
||||
TextureView {
|
||||
id: TextureViewId(Uuid::new_v4()),
|
||||
id: TextureViewId::new(),
|
||||
value: TextureViewValue::TextureView(ErasedTextureView::new(value)),
|
||||
}
|
||||
}
|
||||
@ -116,7 +110,7 @@ impl From<wgpu::SurfaceTexture> for TextureView {
|
||||
let texture = ErasedSurfaceTexture::new(value);
|
||||
|
||||
TextureView {
|
||||
id: TextureViewId(Uuid::new_v4()),
|
||||
id: TextureViewId::new(),
|
||||
value: TextureViewValue::SurfaceTexture { texture, view },
|
||||
}
|
||||
}
|
||||
@ -134,10 +128,7 @@ impl Deref for TextureView {
|
||||
}
|
||||
}
|
||||
|
||||
/// A [`Sampler`] identifier.
|
||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
||||
pub struct SamplerId(Uuid);
|
||||
|
||||
define_atomic_id!(SamplerId);
|
||||
render_resource_wrapper!(ErasedSampler, wgpu::Sampler);
|
||||
|
||||
/// A Sampler defines how a pipeline will sample from a [`TextureView`].
|
||||
@ -162,7 +153,7 @@ impl Sampler {
|
||||
impl From<wgpu::Sampler> for Sampler {
|
||||
fn from(value: wgpu::Sampler) -> Self {
|
||||
Sampler {
|
||||
id: SamplerId(Uuid::new_v4()),
|
||||
id: SamplerId::new(),
|
||||
value: ErasedSampler::new(value),
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user