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 track::{Tracker};
|
||||
use {
|
||||
Stored,
|
||||
CommandBufferId, RenderPassId,
|
||||
@ -14,6 +15,7 @@ pub struct RenderPass<B: hal::Backend> {
|
||||
raw: B::CommandBuffer,
|
||||
parent: B::CommandBuffer,
|
||||
cmb_id: Stored<CommandBufferId>,
|
||||
tracker: Tracker,
|
||||
}
|
||||
|
||||
impl<B: hal::Backend> RenderPass<B> {
|
||||
@ -26,6 +28,7 @@ impl<B: hal::Backend> RenderPass<B> {
|
||||
raw,
|
||||
parent,
|
||||
cmb_id: Stored(cmb_id),
|
||||
tracker: Tracker::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -244,7 +244,9 @@ fn checked_u32_as_u16(value: u32) -> 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 resource::TextureDimension::*;
|
||||
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 {
|
||||
use hal::image::Usage as H;
|
||||
use resource::{
|
||||
TextureUsageFlags_TRANSFER_SRC, TextureUsageFlags_TRANSFER_DST, TextureUsageFlags_SAMPLED,
|
||||
TextureUsageFlags_STORAGE, TextureUsageFlags_OUTPUT_ATTACHMENT,
|
||||
};
|
||||
let mut value = H::empty();
|
||||
if 0 != flags & TextureUsageFlags_TRANSFER_SRC {
|
||||
value |= H::TRANSFER_SRC;
|
||||
pub(crate) fn map_texture_usage_flags(
|
||||
flags: resource::TextureUsageFlags, format: hal::format::Format
|
||||
) -> hal::image::Usage {
|
||||
use hal::image::Usage as U;
|
||||
use resource::TextureUsageFlags as W;
|
||||
|
||||
let mut value = U::empty();
|
||||
if flags.contains(W::TRANSFER_SRC) {
|
||||
value |= U::TRANSFER_SRC;
|
||||
}
|
||||
if 0 != flags & TextureUsageFlags_TRANSFER_DST {
|
||||
value |= H::TRANSFER_DST;
|
||||
if flags.contains(W::TRANSFER_DST) {
|
||||
value |= U::TRANSFER_DST;
|
||||
}
|
||||
if 0 != flags & TextureUsageFlags_SAMPLED {
|
||||
value |= H::SAMPLED;
|
||||
if flags.contains(W::SAMPLED) {
|
||||
value |= U::SAMPLED;
|
||||
}
|
||||
if 0 != flags & TextureUsageFlags_STORAGE {
|
||||
value |= H::STORAGE;
|
||||
if flags.contains(W::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) {
|
||||
value |= H::DEPTH_STENCIL_ATTACHMENT;
|
||||
value |= U::DEPTH_STENCIL_ATTACHMENT;
|
||||
} else {
|
||||
value |= H::COLOR_ATTACHMENT;
|
||||
value |= U::COLOR_ATTACHMENT;
|
||||
}
|
||||
}
|
||||
// Note: TextureUsageFlags::Present does not need to be handled explicitly
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
use {back, binding_model, command, conv, pipeline, resource};
|
||||
use registry::{HUB, Items, Registry};
|
||||
use track::{Tracker, UsePermit};
|
||||
use {
|
||||
Stored,
|
||||
AttachmentStateId, BindGroupLayoutId, BlendStateId, CommandBufferId, DepthStencilStateId,
|
||||
DeviceId, PipelineLayoutId, QueueId, RenderPipelineId, ShaderModuleId, TextureId,
|
||||
};
|
||||
@ -18,6 +20,7 @@ pub struct Device<B: hal::Backend> {
|
||||
queue_group: hal::QueueGroup<B, hal::General>,
|
||||
mem_allocator: Heaps<B::Memory>,
|
||||
pub(crate) com_allocator: command::CommandAllocator<B>,
|
||||
tracker: Tracker,
|
||||
mem_props: hal::MemoryProperties,
|
||||
}
|
||||
|
||||
@ -53,6 +56,7 @@ impl<B: hal::Backend> Device<B> {
|
||||
mem_allocator,
|
||||
com_allocator: command::CommandAllocator::new(queue_group.family()),
|
||||
queue_group,
|
||||
tracker: Tracker::default(),
|
||||
mem_props,
|
||||
}
|
||||
}
|
||||
@ -101,11 +105,16 @@ pub extern "C" fn wgpu_device_create_texture(
|
||||
.raw
|
||||
.bind_image_memory(&image_memory, 0, image_unbound)
|
||||
.unwrap();
|
||||
HUB.textures
|
||||
|
||||
let id = HUB.textures
|
||||
.lock()
|
||||
.register(resource::Texture {
|
||||
raw: bound_image,
|
||||
})
|
||||
});
|
||||
device.tracker.use_texture(Stored(id), resource::TextureUsageFlags::empty(), UsePermit::empty())
|
||||
.expect("Resource somehow is already registered");
|
||||
|
||||
id
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@ -216,7 +225,7 @@ pub extern "C" fn wgpu_device_create_command_buffer(
|
||||
_desc: &command::CommandBufferDescriptor,
|
||||
) -> CommandBufferId {
|
||||
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);
|
||||
cmd_buf.raw.last_mut().unwrap().begin(
|
||||
|
||||
@ -29,6 +29,7 @@ mod instance;
|
||||
mod pipeline;
|
||||
mod registry;
|
||||
mod resource;
|
||||
mod track;
|
||||
|
||||
pub use self::binding_model::*;
|
||||
pub use self::command::*;
|
||||
@ -40,7 +41,7 @@ pub use self::resource::*;
|
||||
use back::Backend as B;
|
||||
use registry::Id;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, Hash, PartialEq, Eq)]
|
||||
struct Stored<T>(T);
|
||||
#[cfg(not(feature = "remote"))]
|
||||
unsafe impl<T> Sync for Stored<T> {}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
use {Extent3d};
|
||||
|
||||
use hal;
|
||||
|
||||
use Extent3d;
|
||||
|
||||
bitflags! {
|
||||
#[repr(transparent)]
|
||||
pub struct BufferUsageFlags: u32 {
|
||||
const NONE = 0;
|
||||
const MAP_READ = 1;
|
||||
const MAP_WRITE = 2;
|
||||
const TRANSFER_SRC = 4;
|
||||
@ -14,6 +14,8 @@ bitflags! {
|
||||
const VERTEX = 32;
|
||||
const UNIFORM = 64;
|
||||
const STORAGE = 128;
|
||||
const NONE = 0;
|
||||
const WRITE_ALL = 2 + 8 + 128;
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,22 +52,19 @@ pub enum TextureFormat {
|
||||
D32FloatS8Uint = 3,
|
||||
}
|
||||
|
||||
// TODO: bitflags
|
||||
pub type TextureUsageFlags = u32;
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub const TextureUsageFlags_NONE: u32 = 0;
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub const TextureUsageFlags_TRANSFER_SRC: u32 = 1;
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub const TextureUsageFlags_TRANSFER_DST: u32 = 2;
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub const TextureUsageFlags_SAMPLED: u32 = 4;
|
||||
#[allow(non_upper_case_globals)]
|
||||
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;
|
||||
bitflags! {
|
||||
#[repr(transparent)]
|
||||
pub struct TextureUsageFlags: u32 {
|
||||
const TRANSFER_SRC = 1;
|
||||
const TRANSFER_DST = 2;
|
||||
const SAMPLED = 4;
|
||||
const STORAGE = 8;
|
||||
const OUTPUT_ATTACHMENT = 16;
|
||||
const PRESENT = 32;
|
||||
const NONE = 0;
|
||||
const WRITE_ALL = 2 + 8 + 16;
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
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