mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
Basic resource tracking
This commit is contained in:
parent
5462690c4a
commit
0fca6930d9
@ -1,4 +1,5 @@
|
|||||||
use registry::{HUB, Items, Registry};
|
use registry::{HUB, Items, Registry};
|
||||||
|
use track::{Tracker};
|
||||||
use {
|
use {
|
||||||
Stored,
|
Stored,
|
||||||
CommandBufferId, RenderPassId,
|
CommandBufferId, RenderPassId,
|
||||||
@ -14,6 +15,7 @@ pub struct RenderPass<B: hal::Backend> {
|
|||||||
raw: B::CommandBuffer,
|
raw: B::CommandBuffer,
|
||||||
parent: B::CommandBuffer,
|
parent: B::CommandBuffer,
|
||||||
cmb_id: Stored<CommandBufferId>,
|
cmb_id: Stored<CommandBufferId>,
|
||||||
|
tracker: Tracker,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: hal::Backend> RenderPass<B> {
|
impl<B: hal::Backend> RenderPass<B> {
|
||||||
@ -26,6 +28,7 @@ impl<B: hal::Backend> RenderPass<B> {
|
|||||||
raw,
|
raw,
|
||||||
parent,
|
parent,
|
||||||
cmb_id: Stored(cmb_id),
|
cmb_id: Stored(cmb_id),
|
||||||
|
tracker: Tracker::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -244,7 +244,9 @@ fn checked_u32_as_u16(value: u32) -> u16 {
|
|||||||
value as u16
|
value as u16
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn map_texture_dimension_size(dimension: resource::TextureDimension, size: Extent3d) -> hal::image::Kind {
|
pub(crate) fn map_texture_dimension_size(
|
||||||
|
dimension: resource::TextureDimension, size: Extent3d
|
||||||
|
) -> hal::image::Kind {
|
||||||
use hal::image::Kind as H;
|
use hal::image::Kind as H;
|
||||||
use resource::TextureDimension::*;
|
use resource::TextureDimension::*;
|
||||||
let Extent3d { width, height, depth } = size;
|
let Extent3d { width, height, depth } = size;
|
||||||
@ -258,30 +260,30 @@ pub(crate) fn map_texture_dimension_size(dimension: resource::TextureDimension,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn map_texture_usage_flags(flags: u32, format: hal::format::Format) -> hal::image::Usage {
|
pub(crate) fn map_texture_usage_flags(
|
||||||
use hal::image::Usage as H;
|
flags: resource::TextureUsageFlags, format: hal::format::Format
|
||||||
use resource::{
|
) -> hal::image::Usage {
|
||||||
TextureUsageFlags_TRANSFER_SRC, TextureUsageFlags_TRANSFER_DST, TextureUsageFlags_SAMPLED,
|
use hal::image::Usage as U;
|
||||||
TextureUsageFlags_STORAGE, TextureUsageFlags_OUTPUT_ATTACHMENT,
|
use resource::TextureUsageFlags as W;
|
||||||
};
|
|
||||||
let mut value = H::empty();
|
let mut value = U::empty();
|
||||||
if 0 != flags & TextureUsageFlags_TRANSFER_SRC {
|
if flags.contains(W::TRANSFER_SRC) {
|
||||||
value |= H::TRANSFER_SRC;
|
value |= U::TRANSFER_SRC;
|
||||||
}
|
}
|
||||||
if 0 != flags & TextureUsageFlags_TRANSFER_DST {
|
if flags.contains(W::TRANSFER_DST) {
|
||||||
value |= H::TRANSFER_DST;
|
value |= U::TRANSFER_DST;
|
||||||
}
|
}
|
||||||
if 0 != flags & TextureUsageFlags_SAMPLED {
|
if flags.contains(W::SAMPLED) {
|
||||||
value |= H::SAMPLED;
|
value |= U::SAMPLED;
|
||||||
}
|
}
|
||||||
if 0 != flags & TextureUsageFlags_STORAGE {
|
if flags.contains(W::STORAGE) {
|
||||||
value |= H::STORAGE;
|
value |= U::STORAGE;
|
||||||
}
|
}
|
||||||
if 0 != flags & TextureUsageFlags_OUTPUT_ATTACHMENT {
|
if flags.contains(W::OUTPUT_ATTACHMENT) {
|
||||||
if format.surface_desc().aspects.intersects(hal::format::Aspects::DEPTH | hal::format::Aspects::STENCIL) {
|
if format.surface_desc().aspects.intersects(hal::format::Aspects::DEPTH | hal::format::Aspects::STENCIL) {
|
||||||
value |= H::DEPTH_STENCIL_ATTACHMENT;
|
value |= U::DEPTH_STENCIL_ATTACHMENT;
|
||||||
} else {
|
} else {
|
||||||
value |= H::COLOR_ATTACHMENT;
|
value |= U::COLOR_ATTACHMENT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Note: TextureUsageFlags::Present does not need to be handled explicitly
|
// Note: TextureUsageFlags::Present does not need to be handled explicitly
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
use {back, binding_model, command, conv, pipeline, resource};
|
use {back, binding_model, command, conv, pipeline, resource};
|
||||||
use registry::{HUB, Items, Registry};
|
use registry::{HUB, Items, Registry};
|
||||||
|
use track::{Tracker, UsePermit};
|
||||||
use {
|
use {
|
||||||
|
Stored,
|
||||||
AttachmentStateId, BindGroupLayoutId, BlendStateId, CommandBufferId, DepthStencilStateId,
|
AttachmentStateId, BindGroupLayoutId, BlendStateId, CommandBufferId, DepthStencilStateId,
|
||||||
DeviceId, PipelineLayoutId, QueueId, RenderPipelineId, ShaderModuleId, TextureId,
|
DeviceId, PipelineLayoutId, QueueId, RenderPipelineId, ShaderModuleId, TextureId,
|
||||||
};
|
};
|
||||||
@ -18,6 +20,7 @@ pub struct Device<B: hal::Backend> {
|
|||||||
queue_group: hal::QueueGroup<B, hal::General>,
|
queue_group: hal::QueueGroup<B, hal::General>,
|
||||||
mem_allocator: Heaps<B::Memory>,
|
mem_allocator: Heaps<B::Memory>,
|
||||||
pub(crate) com_allocator: command::CommandAllocator<B>,
|
pub(crate) com_allocator: command::CommandAllocator<B>,
|
||||||
|
tracker: Tracker,
|
||||||
mem_props: hal::MemoryProperties,
|
mem_props: hal::MemoryProperties,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,6 +56,7 @@ impl<B: hal::Backend> Device<B> {
|
|||||||
mem_allocator,
|
mem_allocator,
|
||||||
com_allocator: command::CommandAllocator::new(queue_group.family()),
|
com_allocator: command::CommandAllocator::new(queue_group.family()),
|
||||||
queue_group,
|
queue_group,
|
||||||
|
tracker: Tracker::default(),
|
||||||
mem_props,
|
mem_props,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,11 +105,16 @@ pub extern "C" fn wgpu_device_create_texture(
|
|||||||
.raw
|
.raw
|
||||||
.bind_image_memory(&image_memory, 0, image_unbound)
|
.bind_image_memory(&image_memory, 0, image_unbound)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
HUB.textures
|
|
||||||
|
let id = HUB.textures
|
||||||
.lock()
|
.lock()
|
||||||
.register(resource::Texture {
|
.register(resource::Texture {
|
||||||
raw: bound_image,
|
raw: bound_image,
|
||||||
})
|
});
|
||||||
|
device.tracker.use_texture(Stored(id), resource::TextureUsageFlags::empty(), UsePermit::empty())
|
||||||
|
.expect("Resource somehow is already registered");
|
||||||
|
|
||||||
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@ -216,7 +225,7 @@ pub extern "C" fn wgpu_device_create_command_buffer(
|
|||||||
_desc: &command::CommandBufferDescriptor,
|
_desc: &command::CommandBufferDescriptor,
|
||||||
) -> CommandBufferId {
|
) -> CommandBufferId {
|
||||||
let mut device_guard = HUB.devices.lock();
|
let mut device_guard = HUB.devices.lock();
|
||||||
let device = device_guard.get_mut(device_id);
|
let device = device_guard.get(device_id);
|
||||||
|
|
||||||
let mut cmd_buf = device.com_allocator.allocate(device_id, &device.raw);
|
let mut cmd_buf = device.com_allocator.allocate(device_id, &device.raw);
|
||||||
cmd_buf.raw.last_mut().unwrap().begin(
|
cmd_buf.raw.last_mut().unwrap().begin(
|
||||||
|
|||||||
@ -29,6 +29,7 @@ mod instance;
|
|||||||
mod pipeline;
|
mod pipeline;
|
||||||
mod registry;
|
mod registry;
|
||||||
mod resource;
|
mod resource;
|
||||||
|
mod track;
|
||||||
|
|
||||||
pub use self::binding_model::*;
|
pub use self::binding_model::*;
|
||||||
pub use self::command::*;
|
pub use self::command::*;
|
||||||
@ -40,7 +41,7 @@ pub use self::resource::*;
|
|||||||
use back::Backend as B;
|
use back::Backend as B;
|
||||||
use registry::Id;
|
use registry::Id;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, Hash, PartialEq, Eq)]
|
||||||
struct Stored<T>(T);
|
struct Stored<T>(T);
|
||||||
#[cfg(not(feature = "remote"))]
|
#[cfg(not(feature = "remote"))]
|
||||||
unsafe impl<T> Sync for Stored<T> {}
|
unsafe impl<T> Sync for Stored<T> {}
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
|
use {Extent3d};
|
||||||
|
|
||||||
use hal;
|
use hal;
|
||||||
|
|
||||||
use Extent3d;
|
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct BufferUsageFlags: u32 {
|
pub struct BufferUsageFlags: u32 {
|
||||||
const NONE = 0;
|
|
||||||
const MAP_READ = 1;
|
const MAP_READ = 1;
|
||||||
const MAP_WRITE = 2;
|
const MAP_WRITE = 2;
|
||||||
const TRANSFER_SRC = 4;
|
const TRANSFER_SRC = 4;
|
||||||
@ -14,6 +14,8 @@ bitflags! {
|
|||||||
const VERTEX = 32;
|
const VERTEX = 32;
|
||||||
const UNIFORM = 64;
|
const UNIFORM = 64;
|
||||||
const STORAGE = 128;
|
const STORAGE = 128;
|
||||||
|
const NONE = 0;
|
||||||
|
const WRITE_ALL = 2 + 8 + 128;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,22 +52,19 @@ pub enum TextureFormat {
|
|||||||
D32FloatS8Uint = 3,
|
D32FloatS8Uint = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: bitflags
|
bitflags! {
|
||||||
pub type TextureUsageFlags = u32;
|
#[repr(transparent)]
|
||||||
#[allow(non_upper_case_globals)]
|
pub struct TextureUsageFlags: u32 {
|
||||||
pub const TextureUsageFlags_NONE: u32 = 0;
|
const TRANSFER_SRC = 1;
|
||||||
#[allow(non_upper_case_globals)]
|
const TRANSFER_DST = 2;
|
||||||
pub const TextureUsageFlags_TRANSFER_SRC: u32 = 1;
|
const SAMPLED = 4;
|
||||||
#[allow(non_upper_case_globals)]
|
const STORAGE = 8;
|
||||||
pub const TextureUsageFlags_TRANSFER_DST: u32 = 2;
|
const OUTPUT_ATTACHMENT = 16;
|
||||||
#[allow(non_upper_case_globals)]
|
const PRESENT = 32;
|
||||||
pub const TextureUsageFlags_SAMPLED: u32 = 4;
|
const NONE = 0;
|
||||||
#[allow(non_upper_case_globals)]
|
const WRITE_ALL = 2 + 8 + 16;
|
||||||
pub const TextureUsageFlags_STORAGE: u32 = 8;
|
}
|
||||||
#[allow(non_upper_case_globals)]
|
}
|
||||||
pub const TextureUsageFlags_OUTPUT_ATTACHMENT: u32 = 16;
|
|
||||||
#[allow(non_upper_case_globals)]
|
|
||||||
pub const TextureUsageFlags_PRESENT: u32 = 32;
|
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct TextureDescriptor {
|
pub struct TextureDescriptor {
|
||||||
|
|||||||
85
wgpu-native/src/track.rs
Normal file
85
wgpu-native/src/track.rs
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
use {Stored, BufferId, TextureId};
|
||||||
|
use resource::{BufferUsageFlags, TextureUsageFlags};
|
||||||
|
|
||||||
|
use std::collections::hash_map::{Entry, HashMap};
|
||||||
|
use std::ops::Range;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub enum UseAction<T> {
|
||||||
|
Init,
|
||||||
|
Keep,
|
||||||
|
Extend { old: T },
|
||||||
|
Replace { old: T },
|
||||||
|
}
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
pub struct UsePermit: u32 {
|
||||||
|
const EXTEND = 1;
|
||||||
|
const REPLACE = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct Tracker {
|
||||||
|
buffers: Mutex<HashMap<Stored<BufferId>, Range<BufferUsageFlags>>>,
|
||||||
|
textures: Mutex<HashMap<Stored<TextureId>, Range<TextureUsageFlags>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tracker {
|
||||||
|
pub(crate) fn use_buffer(
|
||||||
|
&self, id: Stored<BufferId>, usage: BufferUsageFlags, permit: UsePermit,
|
||||||
|
) -> Result<UseAction<BufferUsageFlags>, BufferUsageFlags> {
|
||||||
|
match self.buffers.lock().unwrap().entry(id) {
|
||||||
|
Entry::Vacant(e) => {
|
||||||
|
e.insert(usage .. usage);
|
||||||
|
Ok(UseAction::Init)
|
||||||
|
}
|
||||||
|
Entry::Occupied(mut e) => {
|
||||||
|
let old = e.get().end;
|
||||||
|
if usage == old {
|
||||||
|
Ok(UseAction::Keep)
|
||||||
|
} else if permit.contains(UsePermit::EXTEND) &&
|
||||||
|
!BufferUsageFlags::WRITE_ALL.intersects(old | usage)
|
||||||
|
{
|
||||||
|
e.get_mut().end |= usage;
|
||||||
|
Ok(UseAction::Extend { old })
|
||||||
|
} else if permit.contains(UsePermit::REPLACE) {
|
||||||
|
e.get_mut().end = usage;
|
||||||
|
Ok(UseAction::Replace { old })
|
||||||
|
} else {
|
||||||
|
Err(old)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn use_texture(
|
||||||
|
&self, id: Stored<TextureId>, usage: TextureUsageFlags, permit: UsePermit,
|
||||||
|
) -> Result<UseAction<TextureUsageFlags>, TextureUsageFlags> {
|
||||||
|
match self.textures.lock().unwrap().entry(id) {
|
||||||
|
Entry::Vacant(e) => {
|
||||||
|
e.insert(usage .. usage);
|
||||||
|
Ok(UseAction::Init)
|
||||||
|
}
|
||||||
|
Entry::Occupied(mut e) => {
|
||||||
|
let old = e.get().end;
|
||||||
|
if usage == old {
|
||||||
|
Ok(UseAction::Keep)
|
||||||
|
} else if permit.contains(UsePermit::EXTEND) &&
|
||||||
|
!TextureUsageFlags::WRITE_ALL.intersects(old | usage)
|
||||||
|
{
|
||||||
|
e.get_mut().end |= usage;
|
||||||
|
Ok(UseAction::Extend { old })
|
||||||
|
} else if permit.contains(UsePermit::REPLACE) {
|
||||||
|
e.get_mut().end = usage;
|
||||||
|
Ok(UseAction::Replace { old })
|
||||||
|
} else {
|
||||||
|
Err(old)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user