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::{
|
use crate::{
|
||||||
|
define_atomic_id,
|
||||||
render_graph::{
|
render_graph::{
|
||||||
Edge, InputSlotError, OutputSlotError, RenderGraphContext, RenderGraphError,
|
Edge, InputSlotError, OutputSlotError, RenderGraphContext, RenderGraphError,
|
||||||
RunSubGraphError, SlotInfo, SlotInfos, SlotType, SlotValue,
|
RunSubGraphError, SlotInfo, SlotInfos, SlotType, SlotValue,
|
||||||
@ -6,28 +7,11 @@ use crate::{
|
|||||||
renderer::RenderContext,
|
renderer::RenderContext,
|
||||||
};
|
};
|
||||||
use bevy_ecs::world::World;
|
use bevy_ecs::world::World;
|
||||||
use bevy_utils::Uuid;
|
|
||||||
use downcast_rs::{impl_downcast, Downcast};
|
use downcast_rs::{impl_downcast, Downcast};
|
||||||
use std::{borrow::Cow, fmt::Debug};
|
use std::{borrow::Cow, fmt::Debug};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
/// A [`Node`] identifier.
|
define_atomic_id!(NodeId);
|
||||||
/// 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A render node that can be added to a [`RenderGraph`](super::RenderGraph).
|
/// 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::{
|
use crate::{
|
||||||
|
define_atomic_id,
|
||||||
prelude::Image,
|
prelude::Image,
|
||||||
render_asset::RenderAssets,
|
render_asset::RenderAssets,
|
||||||
render_resource::{BindGroupLayout, Buffer, Sampler, TextureView},
|
render_resource::{resource_macros::*, BindGroupLayout, Buffer, Sampler, TextureView},
|
||||||
renderer::RenderDevice,
|
renderer::RenderDevice,
|
||||||
texture::FallbackImage,
|
texture::FallbackImage,
|
||||||
};
|
};
|
||||||
use bevy_reflect::Uuid;
|
pub use bevy_render_macros::AsBindGroup;
|
||||||
|
use encase::ShaderType;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use wgpu::BindingResource;
|
use wgpu::BindingResource;
|
||||||
|
|
||||||
use crate::render_resource::resource_macros::*;
|
define_atomic_id!(BindGroupId);
|
||||||
render_resource_wrapper!(ErasedBindGroup, wgpu::BindGroup);
|
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)
|
/// Bind groups are responsible for binding render resources (e.g. buffers, textures, samplers)
|
||||||
/// to a [`TrackedRenderPass`](crate::render_phase::TrackedRenderPass).
|
/// to a [`TrackedRenderPass`](crate::render_phase::TrackedRenderPass).
|
||||||
/// This makes them accessible in the pipeline (shaders) as uniforms.
|
/// This makes them accessible in the pipeline (shaders) as uniforms.
|
||||||
@ -42,7 +37,7 @@ impl BindGroup {
|
|||||||
impl From<wgpu::BindGroup> for BindGroup {
|
impl From<wgpu::BindGroup> for BindGroup {
|
||||||
fn from(value: wgpu::BindGroup) -> Self {
|
fn from(value: wgpu::BindGroup) -> Self {
|
||||||
BindGroup {
|
BindGroup {
|
||||||
id: BindGroupId(Uuid::new_v4()),
|
id: BindGroupId::new(),
|
||||||
value: ErasedBindGroup::new(value),
|
value: ErasedBindGroup::new(value),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,7 @@
|
|||||||
use crate::render_resource::resource_macros::*;
|
use crate::{define_atomic_id, render_resource::resource_macros::*};
|
||||||
use bevy_reflect::Uuid;
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
define_atomic_id!(BindGroupLayoutId);
|
||||||
pub struct BindGroupLayoutId(Uuid);
|
|
||||||
|
|
||||||
render_resource_wrapper!(ErasedBindGroupLayout, wgpu::BindGroupLayout);
|
render_resource_wrapper!(ErasedBindGroupLayout, wgpu::BindGroupLayout);
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -34,7 +31,7 @@ impl BindGroupLayout {
|
|||||||
impl From<wgpu::BindGroupLayout> for BindGroupLayout {
|
impl From<wgpu::BindGroupLayout> for BindGroupLayout {
|
||||||
fn from(value: wgpu::BindGroupLayout) -> Self {
|
fn from(value: wgpu::BindGroupLayout) -> Self {
|
||||||
BindGroupLayout {
|
BindGroupLayout {
|
||||||
id: BindGroupLayoutId(Uuid::new_v4()),
|
id: BindGroupLayoutId::new(),
|
||||||
value: ErasedBindGroupLayout::new(value),
|
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 std::ops::{Bound, Deref, RangeBounds};
|
||||||
|
|
||||||
use crate::render_resource::resource_macros::*;
|
define_atomic_id!(BufferId);
|
||||||
|
|
||||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
|
||||||
pub struct BufferId(Uuid);
|
|
||||||
|
|
||||||
render_resource_wrapper!(ErasedBuffer, wgpu::Buffer);
|
render_resource_wrapper!(ErasedBuffer, wgpu::Buffer);
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -42,7 +38,7 @@ impl Buffer {
|
|||||||
impl From<wgpu::Buffer> for Buffer {
|
impl From<wgpu::Buffer> for Buffer {
|
||||||
fn from(value: wgpu::Buffer) -> Self {
|
fn from(value: wgpu::Buffer) -> Self {
|
||||||
Buffer {
|
Buffer {
|
||||||
id: BufferId(Uuid::new_v4()),
|
id: BufferId::new(),
|
||||||
value: ErasedBuffer::new(value),
|
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_asset::Handle;
|
||||||
use bevy_reflect::Uuid;
|
|
||||||
use std::{borrow::Cow, ops::Deref};
|
use std::{borrow::Cow, ops::Deref};
|
||||||
use wgpu::{
|
use wgpu::{
|
||||||
BufferAddress, ColorTargetState, DepthStencilState, MultisampleState, PrimitiveState,
|
BufferAddress, ColorTargetState, DepthStencilState, MultisampleState, PrimitiveState,
|
||||||
VertexAttribute, VertexFormat, VertexStepMode,
|
VertexAttribute, VertexFormat, VertexStepMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::ShaderDefVal;
|
define_atomic_id!(RenderPipelineId);
|
||||||
use crate::render_resource::resource_macros::*;
|
|
||||||
|
|
||||||
/// A [`RenderPipeline`] identifier.
|
|
||||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
|
||||||
pub struct RenderPipelineId(Uuid);
|
|
||||||
|
|
||||||
render_resource_wrapper!(ErasedRenderPipeline, wgpu::RenderPipeline);
|
render_resource_wrapper!(ErasedRenderPipeline, wgpu::RenderPipeline);
|
||||||
|
|
||||||
/// A [`RenderPipeline`] represents a graphics pipeline and its stages (shaders), bindings and vertex buffers.
|
/// 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 {
|
impl From<wgpu::RenderPipeline> for RenderPipeline {
|
||||||
fn from(value: wgpu::RenderPipeline) -> Self {
|
fn from(value: wgpu::RenderPipeline) -> Self {
|
||||||
RenderPipeline {
|
RenderPipeline {
|
||||||
id: RenderPipelineId(Uuid::new_v4()),
|
id: RenderPipelineId::new(),
|
||||||
value: ErasedRenderPipeline::new(value),
|
value: ErasedRenderPipeline::new(value),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -51,10 +48,7 @@ impl Deref for RenderPipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A [`ComputePipeline`] identifier.
|
define_atomic_id!(ComputePipelineId);
|
||||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
|
||||||
pub struct ComputePipelineId(Uuid);
|
|
||||||
|
|
||||||
render_resource_wrapper!(ErasedComputePipeline, wgpu::ComputePipeline);
|
render_resource_wrapper!(ErasedComputePipeline, wgpu::ComputePipeline);
|
||||||
|
|
||||||
/// A [`ComputePipeline`] represents a compute pipeline and its single shader stage.
|
/// A [`ComputePipeline`] represents a compute pipeline and its single shader stage.
|
||||||
@ -78,7 +72,7 @@ impl ComputePipeline {
|
|||||||
impl From<wgpu::ComputePipeline> for ComputePipeline {
|
impl From<wgpu::ComputePipeline> for ComputePipeline {
|
||||||
fn from(value: wgpu::ComputePipeline) -> Self {
|
fn from(value: wgpu::ComputePipeline) -> Self {
|
||||||
ComputePipeline {
|
ComputePipeline {
|
||||||
id: ComputePipelineId(Uuid::new_v4()),
|
id: ComputePipelineId::new(),
|
||||||
value: ErasedComputePipeline::new(value),
|
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;
|
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_asset::{AssetLoader, AssetPath, Handle, LoadContext, LoadedAsset};
|
||||||
use bevy_reflect::{TypeUuid, Uuid};
|
use bevy_reflect::TypeUuid;
|
||||||
use bevy_utils::{tracing::error, BoxedFuture, HashMap};
|
use bevy_utils::{tracing::error, BoxedFuture, HashMap};
|
||||||
use naga::back::wgsl::WriterFlags;
|
use naga::{back::wgsl::WriterFlags, valid::Capabilities, valid::ModuleInfo, Module};
|
||||||
use naga::valid::Capabilities;
|
|
||||||
use naga::{valid::ModuleInfo, Module};
|
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::{borrow::Cow, marker::Copy, ops::Deref, path::PathBuf, str::FromStr};
|
use std::{borrow::Cow, marker::Copy, ops::Deref, path::PathBuf, str::FromStr};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use wgpu::Features;
|
use wgpu::{util::make_spirv, Features, ShaderModuleDescriptor, ShaderSource};
|
||||||
use wgpu::{util::make_spirv, ShaderModuleDescriptor, ShaderSource};
|
|
||||||
|
|
||||||
use super::ShaderDefVal;
|
define_atomic_id!(ShaderId);
|
||||||
|
|
||||||
#[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())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum ShaderReflectError {
|
pub enum ShaderReflectError {
|
||||||
|
|||||||
@ -1,12 +1,9 @@
|
|||||||
use bevy_utils::Uuid;
|
use crate::define_atomic_id;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
use crate::render_resource::resource_macros::*;
|
use crate::render_resource::resource_macros::*;
|
||||||
|
|
||||||
/// A [`Texture`] identifier.
|
define_atomic_id!(TextureId);
|
||||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
|
||||||
pub struct TextureId(Uuid);
|
|
||||||
|
|
||||||
render_resource_wrapper!(ErasedTexture, wgpu::Texture);
|
render_resource_wrapper!(ErasedTexture, wgpu::Texture);
|
||||||
|
|
||||||
/// A GPU-accessible texture.
|
/// A GPU-accessible texture.
|
||||||
@ -35,7 +32,7 @@ impl Texture {
|
|||||||
impl From<wgpu::Texture> for Texture {
|
impl From<wgpu::Texture> for Texture {
|
||||||
fn from(value: wgpu::Texture) -> Self {
|
fn from(value: wgpu::Texture) -> Self {
|
||||||
Texture {
|
Texture {
|
||||||
id: TextureId(Uuid::new_v4()),
|
id: TextureId::new(),
|
||||||
value: ErasedTexture::new(value),
|
value: ErasedTexture::new(value),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,10 +47,7 @@ impl Deref for Texture {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A [`TextureView`] identifier.
|
define_atomic_id!(TextureViewId);
|
||||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
|
||||||
pub struct TextureViewId(Uuid);
|
|
||||||
|
|
||||||
render_resource_wrapper!(ErasedTextureView, wgpu::TextureView);
|
render_resource_wrapper!(ErasedTextureView, wgpu::TextureView);
|
||||||
render_resource_wrapper!(ErasedSurfaceTexture, wgpu::SurfaceTexture);
|
render_resource_wrapper!(ErasedSurfaceTexture, wgpu::SurfaceTexture);
|
||||||
|
|
||||||
@ -104,7 +98,7 @@ impl TextureView {
|
|||||||
impl From<wgpu::TextureView> for TextureView {
|
impl From<wgpu::TextureView> for TextureView {
|
||||||
fn from(value: wgpu::TextureView) -> Self {
|
fn from(value: wgpu::TextureView) -> Self {
|
||||||
TextureView {
|
TextureView {
|
||||||
id: TextureViewId(Uuid::new_v4()),
|
id: TextureViewId::new(),
|
||||||
value: TextureViewValue::TextureView(ErasedTextureView::new(value)),
|
value: TextureViewValue::TextureView(ErasedTextureView::new(value)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,7 +110,7 @@ impl From<wgpu::SurfaceTexture> for TextureView {
|
|||||||
let texture = ErasedSurfaceTexture::new(value);
|
let texture = ErasedSurfaceTexture::new(value);
|
||||||
|
|
||||||
TextureView {
|
TextureView {
|
||||||
id: TextureViewId(Uuid::new_v4()),
|
id: TextureViewId::new(),
|
||||||
value: TextureViewValue::SurfaceTexture { texture, view },
|
value: TextureViewValue::SurfaceTexture { texture, view },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -134,10 +128,7 @@ impl Deref for TextureView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A [`Sampler`] identifier.
|
define_atomic_id!(SamplerId);
|
||||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
|
||||||
pub struct SamplerId(Uuid);
|
|
||||||
|
|
||||||
render_resource_wrapper!(ErasedSampler, wgpu::Sampler);
|
render_resource_wrapper!(ErasedSampler, wgpu::Sampler);
|
||||||
|
|
||||||
/// A Sampler defines how a pipeline will sample from a [`TextureView`].
|
/// A Sampler defines how a pipeline will sample from a [`TextureView`].
|
||||||
@ -162,7 +153,7 @@ impl Sampler {
|
|||||||
impl From<wgpu::Sampler> for Sampler {
|
impl From<wgpu::Sampler> for Sampler {
|
||||||
fn from(value: wgpu::Sampler) -> Self {
|
fn from(value: wgpu::Sampler) -> Self {
|
||||||
Sampler {
|
Sampler {
|
||||||
id: SamplerId(Uuid::new_v4()),
|
id: SamplerId::new(),
|
||||||
value: ErasedSampler::new(value),
|
value: ErasedSampler::new(value),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user