mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
Update render pass and framebuffers logic to the latest gfx-hal
This commit is contained in:
parent
4ce449c89f
commit
012569845d
25
Cargo.lock
generated
25
Cargo.lock
generated
@ -441,7 +441,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gfx-auxil"
|
name = "gfx-auxil"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
source = "git+https://github.com/gfx-rs/gfx?rev=6b3a1e36939473f0062232baf11e1deacd6605f4#6b3a1e36939473f0062232baf11e1deacd6605f4"
|
source = "git+https://github.com/gfx-rs/gfx?rev=006f0c00782d5f602b4afa8e1fa9ffc2085af997#006f0c00782d5f602b4afa8e1fa9ffc2085af997"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fxhash",
|
"fxhash",
|
||||||
"gfx-hal",
|
"gfx-hal",
|
||||||
@ -451,7 +451,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gfx-backend-dx11"
|
name = "gfx-backend-dx11"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "git+https://github.com/gfx-rs/gfx?rev=6b3a1e36939473f0062232baf11e1deacd6605f4#6b3a1e36939473f0062232baf11e1deacd6605f4"
|
source = "git+https://github.com/gfx-rs/gfx?rev=006f0c00782d5f602b4afa8e1fa9ffc2085af997#006f0c00782d5f602b4afa8e1fa9ffc2085af997"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
@ -472,7 +472,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gfx-backend-dx12"
|
name = "gfx-backend-dx12"
|
||||||
version = "0.6.2"
|
version = "0.6.2"
|
||||||
source = "git+https://github.com/gfx-rs/gfx?rev=6b3a1e36939473f0062232baf11e1deacd6605f4#6b3a1e36939473f0062232baf11e1deacd6605f4"
|
source = "git+https://github.com/gfx-rs/gfx?rev=006f0c00782d5f602b4afa8e1fa9ffc2085af997#006f0c00782d5f602b4afa8e1fa9ffc2085af997"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"bit-set",
|
"bit-set",
|
||||||
@ -492,7 +492,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gfx-backend-empty"
|
name = "gfx-backend-empty"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "git+https://github.com/gfx-rs/gfx?rev=6b3a1e36939473f0062232baf11e1deacd6605f4#6b3a1e36939473f0062232baf11e1deacd6605f4"
|
source = "git+https://github.com/gfx-rs/gfx?rev=006f0c00782d5f602b4afa8e1fa9ffc2085af997#006f0c00782d5f602b4afa8e1fa9ffc2085af997"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gfx-hal",
|
"gfx-hal",
|
||||||
"log",
|
"log",
|
||||||
@ -502,7 +502,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gfx-backend-gl"
|
name = "gfx-backend-gl"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "git+https://github.com/gfx-rs/gfx?rev=6b3a1e36939473f0062232baf11e1deacd6605f4#6b3a1e36939473f0062232baf11e1deacd6605f4"
|
source = "git+https://github.com/gfx-rs/gfx?rev=006f0c00782d5f602b4afa8e1fa9ffc2085af997#006f0c00782d5f602b4afa8e1fa9ffc2085af997"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
@ -525,7 +525,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gfx-backend-metal"
|
name = "gfx-backend-metal"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "git+https://github.com/gfx-rs/gfx?rev=6b3a1e36939473f0062232baf11e1deacd6605f4#6b3a1e36939473f0062232baf11e1deacd6605f4"
|
source = "git+https://github.com/gfx-rs/gfx?rev=006f0c00782d5f602b4afa8e1fa9ffc2085af997#006f0c00782d5f602b4afa8e1fa9ffc2085af997"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
@ -535,7 +535,6 @@ dependencies = [
|
|||||||
"foreign-types",
|
"foreign-types",
|
||||||
"gfx-auxil",
|
"gfx-auxil",
|
||||||
"gfx-hal",
|
"gfx-hal",
|
||||||
"lazy_static",
|
|
||||||
"log",
|
"log",
|
||||||
"metal",
|
"metal",
|
||||||
"naga",
|
"naga",
|
||||||
@ -550,7 +549,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gfx-backend-vulkan"
|
name = "gfx-backend-vulkan"
|
||||||
version = "0.6.5"
|
version = "0.6.5"
|
||||||
source = "git+https://github.com/gfx-rs/gfx?rev=6b3a1e36939473f0062232baf11e1deacd6605f4#6b3a1e36939473f0062232baf11e1deacd6605f4"
|
source = "git+https://github.com/gfx-rs/gfx?rev=006f0c00782d5f602b4afa8e1fa9ffc2085af997#006f0c00782d5f602b4afa8e1fa9ffc2085af997"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"ash",
|
"ash",
|
||||||
@ -558,10 +557,10 @@ dependencies = [
|
|||||||
"core-graphics-types",
|
"core-graphics-types",
|
||||||
"gfx-hal",
|
"gfx-hal",
|
||||||
"inplace_it",
|
"inplace_it",
|
||||||
"lazy_static",
|
|
||||||
"log",
|
"log",
|
||||||
"naga",
|
"naga",
|
||||||
"objc",
|
"objc",
|
||||||
|
"parking_lot 0.11.0",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
@ -570,7 +569,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gfx-hal"
|
name = "gfx-hal"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "git+https://github.com/gfx-rs/gfx?rev=6b3a1e36939473f0062232baf11e1deacd6605f4#6b3a1e36939473f0062232baf11e1deacd6605f4"
|
source = "git+https://github.com/gfx-rs/gfx?rev=006f0c00782d5f602b4afa8e1fa9ffc2085af997#006f0c00782d5f602b4afa8e1fa9ffc2085af997"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"naga",
|
"naga",
|
||||||
@ -580,9 +579,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glow"
|
name = "glow"
|
||||||
version = "0.6.1"
|
version = "0.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1625b792e2f9267116dd41eb7d325e0ea2572ceba5069451906745e04f852f33"
|
checksum = "3eac04632dc8c047fb70d658f8479583e1bb084859f67a150227769a10fc161f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"slotmap",
|
"slotmap",
|
||||||
@ -1209,7 +1208,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "range-alloc"
|
name = "range-alloc"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
source = "git+https://github.com/gfx-rs/gfx?rev=6b3a1e36939473f0062232baf11e1deacd6605f4#6b3a1e36939473f0062232baf11e1deacd6605f4"
|
source = "git+https://github.com/gfx-rs/gfx?rev=006f0c00782d5f602b4afa8e1fa9ffc2085af997#006f0c00782d5f602b4afa8e1fa9ffc2085af997"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "raw-window-handle"
|
name = "raw-window-handle"
|
||||||
|
|||||||
@ -6,7 +6,7 @@ members = [
|
|||||||
"wgpu-types",
|
"wgpu-types",
|
||||||
]
|
]
|
||||||
|
|
||||||
#[patch."https://github.com/gfx-rs/gfx"]
|
[patch."https://github.com/gfx-rs/gfx"]
|
||||||
#hal = { package = "gfx-hal", path = "../gfx/src/hal" }
|
#hal = { package = "gfx-hal", path = "../gfx/src/hal" }
|
||||||
#gfx-backend-vulkan = { path = "../gfx/src/backend/vulkan", features = ["naga"] }
|
#gfx-backend-vulkan = { path = "../gfx/src/backend/vulkan", features = ["naga"] }
|
||||||
#gfx-backend-metal = { path = "../gfx/src/backend/metal", features = ["naga"] }
|
#gfx-backend-metal = { path = "../gfx/src/backend/metal", features = ["naga"] }
|
||||||
@ -15,5 +15,5 @@ members = [
|
|||||||
#gfx-backend-dx11 = { path = "../gfx/src/backend/dx11" }
|
#gfx-backend-dx11 = { path = "../gfx/src/backend/dx11" }
|
||||||
#gfx-backend-empty = { path = "../gfx/src/backend/empty" }
|
#gfx-backend-empty = { path = "../gfx/src/backend/empty" }
|
||||||
|
|
||||||
#[patch."https://github.com/gfx-rs/naga"]
|
[patch."https://github.com/gfx-rs/naga"]
|
||||||
#naga = { path = "../naga" }
|
#naga = { path = "../naga" }
|
||||||
|
|||||||
@ -36,24 +36,24 @@ thiserror = "1"
|
|||||||
gpu-alloc = { git = "https://github.com/zakarumych/gpu-alloc", rev = "29e761f24edc50e28d238e723503b146d55d222e", features = ["tracing"] }
|
gpu-alloc = { git = "https://github.com/zakarumych/gpu-alloc", rev = "29e761f24edc50e28d238e723503b146d55d222e", features = ["tracing"] }
|
||||||
gpu-descriptor = { git = "https://github.com/zakarumych/gpu-descriptor", rev = "df74fd8c7bea03149058a41aab0e4fe04077b266", features = ["tracing"] }
|
gpu-descriptor = { git = "https://github.com/zakarumych/gpu-descriptor", rev = "df74fd8c7bea03149058a41aab0e4fe04077b266", features = ["tracing"] }
|
||||||
|
|
||||||
hal = { package = "gfx-hal", git = "https://github.com/gfx-rs/gfx", rev = "6b3a1e36939473f0062232baf11e1deacd6605f4" }
|
hal = { package = "gfx-hal", git = "https://github.com/gfx-rs/gfx", rev = "006f0c00782d5f602b4afa8e1fa9ffc2085af997" }
|
||||||
gfx-backend-empty = { git = "https://github.com/gfx-rs/gfx", rev = "6b3a1e36939473f0062232baf11e1deacd6605f4" }
|
gfx-backend-empty = { git = "https://github.com/gfx-rs/gfx", rev = "006f0c00782d5f602b4afa8e1fa9ffc2085af997" }
|
||||||
|
|
||||||
[target.'cfg(all(not(target_arch = "wasm32"), all(unix, not(target_os = "ios"), not(target_os = "macos"))))'.dependencies]
|
[target.'cfg(all(not(target_arch = "wasm32"), all(unix, not(target_os = "ios"), not(target_os = "macos"))))'.dependencies]
|
||||||
gfx-backend-vulkan = { git = "https://github.com/gfx-rs/gfx", rev = "6b3a1e36939473f0062232baf11e1deacd6605f4", features = ["naga"] }
|
gfx-backend-vulkan = { git = "https://github.com/gfx-rs/gfx", rev = "006f0c00782d5f602b4afa8e1fa9ffc2085af997", features = ["naga"] }
|
||||||
gfx-backend-gl = { git = "https://github.com/gfx-rs/gfx", rev = "6b3a1e36939473f0062232baf11e1deacd6605f4", features = ["naga"] }
|
gfx-backend-gl = { git = "https://github.com/gfx-rs/gfx", rev = "006f0c00782d5f602b4afa8e1fa9ffc2085af997", features = ["naga"] }
|
||||||
|
|
||||||
[target.'cfg(all(not(target_arch = "wasm32"), any(target_os = "ios", target_os = "macos")))'.dependencies]
|
[target.'cfg(all(not(target_arch = "wasm32"), any(target_os = "ios", target_os = "macos")))'.dependencies]
|
||||||
gfx-backend-metal = { git = "https://github.com/gfx-rs/gfx", rev = "6b3a1e36939473f0062232baf11e1deacd6605f4", features = ["naga"] }
|
gfx-backend-metal = { git = "https://github.com/gfx-rs/gfx", rev = "006f0c00782d5f602b4afa8e1fa9ffc2085af997", features = ["naga"] }
|
||||||
gfx-backend-vulkan = { git = "https://github.com/gfx-rs/gfx", rev = "6b3a1e36939473f0062232baf11e1deacd6605f4", optional = true }
|
gfx-backend-vulkan = { git = "https://github.com/gfx-rs/gfx", rev = "006f0c00782d5f602b4afa8e1fa9ffc2085af997", optional = true }
|
||||||
|
|
||||||
[target.'cfg(all(not(target_arch = "wasm32"), windows))'.dependencies]
|
[target.'cfg(all(not(target_arch = "wasm32"), windows))'.dependencies]
|
||||||
gfx-backend-dx12 = { git = "https://github.com/gfx-rs/gfx", rev = "6b3a1e36939473f0062232baf11e1deacd6605f4" }
|
gfx-backend-dx12 = { git = "https://github.com/gfx-rs/gfx", rev = "006f0c00782d5f602b4afa8e1fa9ffc2085af997" }
|
||||||
gfx-backend-dx11 = { git = "https://github.com/gfx-rs/gfx", rev = "6b3a1e36939473f0062232baf11e1deacd6605f4" }
|
gfx-backend-dx11 = { git = "https://github.com/gfx-rs/gfx", rev = "006f0c00782d5f602b4afa8e1fa9ffc2085af997" }
|
||||||
gfx-backend-vulkan = { git = "https://github.com/gfx-rs/gfx", rev = "6b3a1e36939473f0062232baf11e1deacd6605f4", features = ["naga"] }
|
gfx-backend-vulkan = { git = "https://github.com/gfx-rs/gfx", rev = "006f0c00782d5f602b4afa8e1fa9ffc2085af997", features = ["naga"] }
|
||||||
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
gfx-backend-gl = { git = "https://github.com/gfx-rs/gfx", rev = "6b3a1e36939473f0062232baf11e1deacd6605f4", features = ["naga"] }
|
gfx-backend-gl = { git = "https://github.com/gfx-rs/gfx", rev = "006f0c00782d5f602b4afa8e1fa9ffc2085af997", features = ["naga"] }
|
||||||
|
|
||||||
[dependencies.naga]
|
[dependencies.naga]
|
||||||
git = "https://github.com/gfx-rs/naga"
|
git = "https://github.com/gfx-rs/naga"
|
||||||
|
|||||||
@ -43,7 +43,7 @@ pub struct CommandBuffer<B: hal::Backend> {
|
|||||||
recorded_thread_id: ThreadId,
|
recorded_thread_id: ThreadId,
|
||||||
pub(crate) device_id: Stored<id::DeviceId>,
|
pub(crate) device_id: Stored<id::DeviceId>,
|
||||||
pub(crate) trackers: TrackerSet,
|
pub(crate) trackers: TrackerSet,
|
||||||
pub(crate) used_swap_chains: SmallVec<[(Stored<id::SwapChainId>, B::Framebuffer); 1]>,
|
pub(crate) used_swap_chains: SmallVec<[Stored<id::SwapChainId>; 1]>,
|
||||||
limits: wgt::Limits,
|
limits: wgt::Limits,
|
||||||
private_features: PrivateFeatures,
|
private_features: PrivateFeatures,
|
||||||
has_labels: bool,
|
has_labels: bool,
|
||||||
@ -217,7 +217,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
Ok(cmd_buf) => {
|
Ok(cmd_buf) => {
|
||||||
cmd_buf.is_recording = false;
|
cmd_buf.is_recording = false;
|
||||||
// stop tracking the swapchain image, if used
|
// stop tracking the swapchain image, if used
|
||||||
for (ref sc_id, _) in cmd_buf.used_swap_chains.iter() {
|
for sc_id in cmd_buf.used_swap_chains.iter() {
|
||||||
let view_id = swap_chain_guard[sc_id.value]
|
let view_id = swap_chain_guard[sc_id.value]
|
||||||
.acquired_view_id
|
.acquired_view_id
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|||||||
@ -11,8 +11,8 @@ use crate::{
|
|||||||
},
|
},
|
||||||
conv,
|
conv,
|
||||||
device::{
|
device::{
|
||||||
AttachmentData, AttachmentDataVec, Device, FramebufferKey, RenderPassCompatibilityError,
|
AttachmentData, AttachmentDataVec, Device, RenderPassCompatibilityError, RenderPassContext,
|
||||||
RenderPassContext, RenderPassKey, MAX_COLOR_TARGETS, MAX_VERTEX_BUFFERS,
|
RenderPassKey, RenderPassLock, MAX_COLOR_TARGETS, MAX_VERTEX_BUFFERS,
|
||||||
},
|
},
|
||||||
hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Storage, Token},
|
hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Storage, Token},
|
||||||
id,
|
id,
|
||||||
@ -42,6 +42,7 @@ use std::{
|
|||||||
borrow::{Borrow, Cow},
|
borrow::{Borrow, Cow},
|
||||||
collections::hash_map::Entry,
|
collections::hash_map::Entry,
|
||||||
fmt, iter,
|
fmt, iter,
|
||||||
|
marker::PhantomData,
|
||||||
num::NonZeroU32,
|
num::NonZeroU32,
|
||||||
ops::Range,
|
ops::Range,
|
||||||
str,
|
str,
|
||||||
@ -503,15 +504,14 @@ struct RenderAttachment<'a> {
|
|||||||
new_use: TextureUse,
|
new_use: TextureUse,
|
||||||
}
|
}
|
||||||
|
|
||||||
type UsedSwapChainInfo<F> = Option<(Stored<id::SwapChainId>, F)>;
|
|
||||||
|
|
||||||
struct RenderPassInfo<'a, B: hal::Backend> {
|
struct RenderPassInfo<'a, B: hal::Backend> {
|
||||||
context: RenderPassContext,
|
context: RenderPassContext,
|
||||||
trackers: TrackerSet,
|
trackers: TrackerSet,
|
||||||
render_attachments: AttachmentDataVec<RenderAttachment<'a>>,
|
render_attachments: AttachmentDataVec<RenderAttachment<'a>>,
|
||||||
used_swapchain_with_framebuffer: UsedSwapChainInfo<B::Framebuffer>,
|
used_swap_chain: Option<Stored<id::SwapChainId>>,
|
||||||
is_ds_read_only: bool,
|
is_ds_read_only: bool,
|
||||||
extent: wgt::Extent3d,
|
extent: wgt::Extent3d,
|
||||||
|
_phantom: PhantomData<B>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, B: GfxBackend> RenderPassInfo<'a, B> {
|
impl<'a, B: GfxBackend> RenderPassInfo<'a, B> {
|
||||||
@ -543,7 +543,6 @@ impl<'a, B: GfxBackend> RenderPassInfo<'a, B> {
|
|||||||
let mut depth_stencil_aspects = hal::format::Aspects::empty();
|
let mut depth_stencil_aspects = hal::format::Aspects::empty();
|
||||||
let mut used_swap_chain = None::<Stored<id::SwapChainId>>;
|
let mut used_swap_chain = None::<Stored<id::SwapChainId>>;
|
||||||
let mut trackers = TrackerSet::new(B::VARIANT);
|
let mut trackers = TrackerSet::new(B::VARIANT);
|
||||||
let mut used_swapchain_with_framebuffer = None;
|
|
||||||
|
|
||||||
let mut add_view = |view: &TextureView<B>| {
|
let mut add_view = |view: &TextureView<B>| {
|
||||||
if let Some(ex) = extent {
|
if let Some(ex) = extent {
|
||||||
@ -809,8 +808,11 @@ impl<'a, B: GfxBackend> RenderPassInfo<'a, B> {
|
|||||||
return Err(RenderPassErrorInner::InvalidSampleCount(sample_count));
|
return Err(RenderPassErrorInner::InvalidSampleCount(sample_count));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut render_pass_cache = device.render_passes.lock();
|
let RenderPassLock {
|
||||||
let render_pass = match render_pass_cache.entry(rp_key.clone()) {
|
ref mut render_passes,
|
||||||
|
ref mut framebuffers,
|
||||||
|
} = *device.render_passes.lock();
|
||||||
|
let render_pass = match render_passes.entry(rp_key.clone()) {
|
||||||
Entry::Occupied(e) => e.into_mut(),
|
Entry::Occupied(e) => e.into_mut(),
|
||||||
Entry::Vacant(entry) => {
|
Entry::Vacant(entry) => {
|
||||||
let color_ids: [hal::pass::AttachmentRef; MAX_COLOR_TARGETS] = [
|
let color_ids: [hal::pass::AttachmentRef; MAX_COLOR_TARGETS] = [
|
||||||
@ -871,82 +873,40 @@ impl<'a, B: GfxBackend> RenderPassInfo<'a, B> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut framebuffer_cache;
|
let view_data = AttachmentData {
|
||||||
let fb_key = FramebufferKey {
|
|
||||||
colors: color_attachments
|
colors: color_attachments
|
||||||
.iter()
|
.iter()
|
||||||
.map(|at| id::Valid(at.attachment))
|
.map(|at| view_guard.get(at.attachment).unwrap())
|
||||||
.collect(),
|
.collect(),
|
||||||
resolves: color_attachments
|
resolves: color_attachments
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|at| at.resolve_target)
|
.filter_map(|at| at.resolve_target)
|
||||||
.map(id::Valid)
|
.map(|attachment| view_guard.get(attachment).unwrap())
|
||||||
.collect(),
|
.collect(),
|
||||||
depth_stencil: depth_stencil_attachment.map(|at| id::Valid(at.attachment)),
|
depth_stencil: depth_stencil_attachment
|
||||||
|
.map(|at| view_guard.get(at.attachment).unwrap()),
|
||||||
};
|
};
|
||||||
|
let fb_key = view_data.map(|view| view.framebuffer_attachment.clone());
|
||||||
let context = RenderPassContext {
|
let context = RenderPassContext {
|
||||||
attachments: AttachmentData {
|
attachments: view_data.map(|view| view.format),
|
||||||
colors: fb_key
|
|
||||||
.colors
|
|
||||||
.iter()
|
|
||||||
.map(|&at| view_guard[at].format)
|
|
||||||
.collect(),
|
|
||||||
resolves: fb_key
|
|
||||||
.resolves
|
|
||||||
.iter()
|
|
||||||
.map(|&at| view_guard[at].format)
|
|
||||||
.collect(),
|
|
||||||
depth_stencil: fb_key.depth_stencil.map(|at| view_guard[at].format),
|
|
||||||
},
|
|
||||||
sample_count,
|
sample_count,
|
||||||
};
|
};
|
||||||
|
|
||||||
let framebuffer = match used_swap_chain.take() {
|
// Cache framebuffers by the device.
|
||||||
Some(sc_id) => {
|
let framebuffer = match framebuffers.entry(fb_key) {
|
||||||
// Always create a new framebuffer and delete it after presentation.
|
Entry::Occupied(e) => e.into_mut(),
|
||||||
let attachments = fb_key
|
Entry::Vacant(e) => {
|
||||||
.all()
|
let fb = unsafe {
|
||||||
.map(|&id| match view_guard[id].inner {
|
|
||||||
TextureViewInner::Native { ref raw, .. } => raw,
|
|
||||||
TextureViewInner::SwapChain { ref image, .. } => Borrow::borrow(image),
|
|
||||||
})
|
|
||||||
.collect::<AttachmentDataVec<_>>();
|
|
||||||
let framebuffer = unsafe {
|
|
||||||
device
|
device
|
||||||
.raw
|
.raw
|
||||||
.create_framebuffer(&render_pass, attachments, extent.unwrap())
|
.create_framebuffer(
|
||||||
|
&render_pass,
|
||||||
|
e.key().all().map(|fat| fat.clone()),
|
||||||
|
extent.unwrap(),
|
||||||
|
)
|
||||||
.or(Err(RenderPassErrorInner::OutOfMemory))?
|
.or(Err(RenderPassErrorInner::OutOfMemory))?
|
||||||
};
|
};
|
||||||
used_swapchain_with_framebuffer = Some((sc_id, framebuffer));
|
e.insert(fb)
|
||||||
&mut used_swapchain_with_framebuffer.as_mut().unwrap().1
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
// Cache framebuffers by the device.
|
|
||||||
framebuffer_cache = device.framebuffers.lock();
|
|
||||||
match framebuffer_cache.entry(fb_key) {
|
|
||||||
Entry::Occupied(e) => e.into_mut(),
|
|
||||||
Entry::Vacant(e) => {
|
|
||||||
let fb = {
|
|
||||||
let attachments = e
|
|
||||||
.key()
|
|
||||||
.all()
|
|
||||||
.map(|&id| match view_guard[id].inner {
|
|
||||||
TextureViewInner::Native { ref raw, .. } => raw,
|
|
||||||
TextureViewInner::SwapChain { ref image, .. } => {
|
|
||||||
Borrow::borrow(image)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<AttachmentDataVec<_>>();
|
|
||||||
unsafe {
|
|
||||||
device
|
|
||||||
.raw
|
|
||||||
.create_framebuffer(&render_pass, attachments, extent.unwrap())
|
|
||||||
.or(Err(RenderPassErrorInner::OutOfMemory))?
|
|
||||||
}
|
|
||||||
};
|
|
||||||
e.insert(fb)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -959,59 +919,75 @@ impl<'a, B: GfxBackend> RenderPassInfo<'a, B> {
|
|||||||
h: ex.height as _,
|
h: ex.height as _,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let raw_views = view_data.map(|view| match view.inner {
|
||||||
|
TextureViewInner::Native { ref raw, .. } => raw,
|
||||||
|
TextureViewInner::SwapChain { ref image, .. } => Borrow::borrow(image),
|
||||||
|
});
|
||||||
|
|
||||||
let clear_values = color_attachments
|
let attachments = color_attachments
|
||||||
.iter()
|
.iter()
|
||||||
.zip(&rp_key.colors)
|
.zip(&rp_key.colors)
|
||||||
.flat_map(|(at, (rat, _layout))| {
|
.zip(raw_views.colors)
|
||||||
match at.channel.load_op {
|
.map(
|
||||||
LoadOp::Load => None,
|
|((at, (rat, _layout)), image_view)| hal::command::RenderAttachmentInfo {
|
||||||
LoadOp::Clear => {
|
image_view,
|
||||||
use hal::format::ChannelType;
|
clear_value: match at.channel.load_op {
|
||||||
//TODO: validate sign/unsign and normalized ranges of the color values
|
LoadOp::Load => Default::default(),
|
||||||
let value = match rat.format.unwrap().base_format().1 {
|
LoadOp::Clear => {
|
||||||
ChannelType::Unorm
|
use hal::format::ChannelType;
|
||||||
| ChannelType::Snorm
|
//TODO: validate sign/unsign and normalized ranges of the color values
|
||||||
| ChannelType::Ufloat
|
let value = match rat.format.unwrap().base_format().1 {
|
||||||
| ChannelType::Sfloat
|
ChannelType::Unorm
|
||||||
| ChannelType::Uscaled
|
| ChannelType::Snorm
|
||||||
| ChannelType::Sscaled
|
| ChannelType::Ufloat
|
||||||
| ChannelType::Srgb => hal::command::ClearColor {
|
| ChannelType::Sfloat
|
||||||
float32: conv::map_color_f32(&at.channel.clear_value),
|
| ChannelType::Uscaled
|
||||||
},
|
| ChannelType::Sscaled
|
||||||
ChannelType::Sint => hal::command::ClearColor {
|
| ChannelType::Srgb => hal::command::ClearColor {
|
||||||
sint32: conv::map_color_i32(&at.channel.clear_value),
|
float32: conv::map_color_f32(&at.channel.clear_value),
|
||||||
},
|
},
|
||||||
ChannelType::Uint => hal::command::ClearColor {
|
ChannelType::Sint => hal::command::ClearColor {
|
||||||
uint32: conv::map_color_u32(&at.channel.clear_value),
|
sint32: conv::map_color_i32(&at.channel.clear_value),
|
||||||
},
|
},
|
||||||
};
|
ChannelType::Uint => hal::command::ClearColor {
|
||||||
Some(hal::command::ClearValue { color: value })
|
uint32: conv::map_color_u32(&at.channel.clear_value),
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
})
|
hal::command::ClearValue { color: value }
|
||||||
.chain(depth_stencil_attachment.and_then(|at| {
|
}
|
||||||
match (at.depth.load_op, at.stencil.load_op) {
|
},
|
||||||
(LoadOp::Load, LoadOp::Load) => None,
|
},
|
||||||
(LoadOp::Clear, _) | (_, LoadOp::Clear) => {
|
)
|
||||||
let value = hal::command::ClearDepthStencil {
|
.chain(raw_views.resolves.into_iter().map(|image_view| {
|
||||||
depth: at.depth.clear_value,
|
hal::command::RenderAttachmentInfo {
|
||||||
stencil: at.stencil.clear_value,
|
image_view,
|
||||||
};
|
clear_value: Default::default(),
|
||||||
Some(hal::command::ClearValue {
|
|
||||||
depth_stencil: value,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.collect::<ArrayVec<[_; MAX_COLOR_TARGETS + 1]>>();
|
.chain(depth_stencil_attachment.zip(raw_views.depth_stencil).map(
|
||||||
|
|(at, image_view)| hal::command::RenderAttachmentInfo {
|
||||||
|
image_view,
|
||||||
|
clear_value: match (at.depth.load_op, at.stencil.load_op) {
|
||||||
|
(LoadOp::Load, LoadOp::Load) => Default::default(),
|
||||||
|
(LoadOp::Clear, _) | (_, LoadOp::Clear) => {
|
||||||
|
let value = hal::command::ClearDepthStencil {
|
||||||
|
depth: at.depth.clear_value,
|
||||||
|
stencil: at.stencil.clear_value,
|
||||||
|
};
|
||||||
|
hal::command::ClearValue {
|
||||||
|
depth_stencil: value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
raw.begin_render_pass(
|
raw.begin_render_pass(
|
||||||
render_pass,
|
render_pass,
|
||||||
framebuffer,
|
framebuffer,
|
||||||
rect,
|
rect,
|
||||||
clear_values,
|
attachments,
|
||||||
hal::command::SubpassContents::Inline,
|
hal::command::SubpassContents::Inline,
|
||||||
);
|
);
|
||||||
raw.set_scissors(0, iter::once(&rect));
|
raw.set_scissors(0, iter::once(&rect));
|
||||||
@ -1028,20 +1004,21 @@ impl<'a, B: GfxBackend> RenderPassInfo<'a, B> {
|
|||||||
context,
|
context,
|
||||||
trackers,
|
trackers,
|
||||||
render_attachments,
|
render_attachments,
|
||||||
used_swapchain_with_framebuffer,
|
used_swap_chain,
|
||||||
is_ds_read_only,
|
is_ds_read_only,
|
||||||
extent: wgt::Extent3d {
|
extent: wgt::Extent3d {
|
||||||
width: attachment_width.ok_or(RenderPassErrorInner::MissingAttachments)?,
|
width: attachment_width.ok_or(RenderPassErrorInner::MissingAttachments)?,
|
||||||
height: attachment_height.ok_or(RenderPassErrorInner::MissingAttachments)?,
|
height: attachment_height.ok_or(RenderPassErrorInner::MissingAttachments)?,
|
||||||
depth: 1,
|
depth: 1,
|
||||||
},
|
},
|
||||||
|
_phantom: PhantomData,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finish(
|
fn finish(
|
||||||
mut self,
|
mut self,
|
||||||
texture_guard: &Storage<Texture<B>, id::TextureId>,
|
texture_guard: &Storage<Texture<B>, id::TextureId>,
|
||||||
) -> Result<(TrackerSet, UsedSwapChainInfo<B::Framebuffer>), RenderPassErrorInner> {
|
) -> Result<(TrackerSet, Option<Stored<id::SwapChainId>>), RenderPassErrorInner> {
|
||||||
for ra in self.render_attachments {
|
for ra in self.render_attachments {
|
||||||
let texture = &texture_guard[ra.texture_id.value];
|
let texture = &texture_guard[ra.texture_id.value];
|
||||||
check_texture_usage(texture.usage, TextureUsage::RENDER_ATTACHMENT)?;
|
check_texture_usage(texture.usage, TextureUsage::RENDER_ATTACHMENT)?;
|
||||||
@ -1072,7 +1049,7 @@ impl<'a, B: GfxBackend> RenderPassInfo<'a, B> {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok((self.trackers, self.used_swapchain_with_framebuffer))
|
Ok((self.trackers, self.used_swap_chain))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1108,7 +1085,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
|
|
||||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||||
|
|
||||||
let (cmd_buf_raw, trackers, used_swapchain_with_framebuffer) = {
|
let (cmd_buf_raw, trackers, used_swapchain) = {
|
||||||
// read-only lock guard
|
// read-only lock guard
|
||||||
let (cmb_guard, mut token) = hub.command_buffers.read(&mut token);
|
let (cmb_guard, mut token) = hub.command_buffers.read(&mut token);
|
||||||
|
|
||||||
@ -1866,9 +1843,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
raw.end_render_pass();
|
raw.end_render_pass();
|
||||||
}
|
}
|
||||||
|
|
||||||
let (trackers, used_swapchain_with_framebuffer) =
|
let (trackers, used_swapchain) = info.finish(&*texture_guard).map_pass_err(scope)?;
|
||||||
info.finish(&*texture_guard).map_pass_err(scope)?;
|
(raw, trackers, used_swapchain)
|
||||||
(raw, trackers, used_swapchain_with_framebuffer)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let (mut cmb_guard, mut token) = hub.command_buffers.write(&mut token);
|
let (mut cmb_guard, mut token) = hub.command_buffers.write(&mut token);
|
||||||
@ -1877,9 +1853,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
let cmd_buf =
|
let cmd_buf =
|
||||||
CommandBuffer::get_encoder_mut(&mut *cmb_guard, encoder_id).map_pass_err(scope)?;
|
CommandBuffer::get_encoder_mut(&mut *cmb_guard, encoder_id).map_pass_err(scope)?;
|
||||||
cmd_buf.has_labels |= base.label.is_some();
|
cmd_buf.has_labels |= base.label.is_some();
|
||||||
cmd_buf
|
cmd_buf.used_swap_chains.extend(used_swapchain);
|
||||||
.used_swap_chains
|
|
||||||
.extend(used_swapchain_with_framebuffer);
|
|
||||||
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "trace")]
|
||||||
if let Some(ref mut list) = cmd_buf.commands {
|
if let Some(ref mut list) = cmd_buf.commands {
|
||||||
|
|||||||
@ -14,7 +14,7 @@ use crate::{
|
|||||||
hub::{GfxBackend, GlobalIdentityHandlerFactory, Hub, Token},
|
hub::{GfxBackend, GlobalIdentityHandlerFactory, Hub, Token},
|
||||||
id, resource,
|
id, resource,
|
||||||
track::TrackerSet,
|
track::TrackerSet,
|
||||||
FastHashMap, RefCount, Stored, SubmissionIndex,
|
RefCount, Stored, SubmissionIndex,
|
||||||
};
|
};
|
||||||
|
|
||||||
use copyless::VecHelper as _;
|
use copyless::VecHelper as _;
|
||||||
@ -636,74 +636,6 @@ impl<B: GfxBackend> LifetimeTracker<B> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn triage_framebuffers<G: GlobalIdentityHandlerFactory>(
|
|
||||||
&mut self,
|
|
||||||
hub: &Hub<B, G>,
|
|
||||||
framebuffers: &mut FastHashMap<super::FramebufferKey, B::Framebuffer>,
|
|
||||||
token: &mut Token<super::Device<B>>,
|
|
||||||
) {
|
|
||||||
let (texture_view_guard, _) = hub.texture_views.read(token);
|
|
||||||
let remove_list = framebuffers
|
|
||||||
.keys()
|
|
||||||
.filter_map(|key| {
|
|
||||||
let mut last_submit = None;
|
|
||||||
let mut needs_cleanup = false;
|
|
||||||
|
|
||||||
// A framebuffer needs to be scheduled for cleanup, if there's at least one
|
|
||||||
// attachment is no longer valid.
|
|
||||||
|
|
||||||
for &at in key.all() {
|
|
||||||
// If this attachment is still registered, it's still valid
|
|
||||||
if texture_view_guard.contains(at.0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This attachment is no longer registered, this framebuffer needs cleanup
|
|
||||||
needs_cleanup = true;
|
|
||||||
|
|
||||||
// Check if there's any active submissions that are still referring to this
|
|
||||||
// attachment, if there are we need to get the greatest submission index, as
|
|
||||||
// that's the last time this attachment is still valid
|
|
||||||
let mut attachment_last_submit = None;
|
|
||||||
for a in &self.active {
|
|
||||||
if a.last_resources.image_views.iter().any(|&(id, _)| id == at) {
|
|
||||||
let max = attachment_last_submit.unwrap_or(0).max(a.index);
|
|
||||||
attachment_last_submit = Some(max);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Between all attachments, we need the smallest index, because that's the last
|
|
||||||
// time this framebuffer is still valid
|
|
||||||
if let Some(attachment_last_submit) = attachment_last_submit {
|
|
||||||
let min = last_submit
|
|
||||||
.unwrap_or(std::usize::MAX)
|
|
||||||
.min(attachment_last_submit);
|
|
||||||
last_submit = Some(min);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if needs_cleanup {
|
|
||||||
Some((key.clone(), last_submit.unwrap_or(0)))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<FastHashMap<_, _>>();
|
|
||||||
|
|
||||||
if !remove_list.is_empty() {
|
|
||||||
tracing::debug!("Free framebuffers {:?}", remove_list);
|
|
||||||
for (ref key, submit_index) in remove_list {
|
|
||||||
let framebuffer = framebuffers.remove(key).unwrap();
|
|
||||||
self.active
|
|
||||||
.iter_mut()
|
|
||||||
.find(|a| a.index == submit_index)
|
|
||||||
.map_or(&mut self.free_resources, |a| &mut a.last_resources)
|
|
||||||
.framebuffers
|
|
||||||
.push(framebuffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn handle_mapping<G: GlobalIdentityHandlerFactory>(
|
pub(crate) fn handle_mapping<G: GlobalIdentityHandlerFactory>(
|
||||||
&mut self,
|
&mut self,
|
||||||
hub: &Hub<B, G>,
|
hub: &Hub<B, G>,
|
||||||
|
|||||||
@ -103,12 +103,20 @@ impl<T> AttachmentData<T> {
|
|||||||
.chain(&self.resolves)
|
.chain(&self.resolves)
|
||||||
.chain(&self.depth_stencil)
|
.chain(&self.depth_stencil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn map<U, F: Fn(&T) -> U>(&self, fun: F) -> AttachmentData<U> {
|
||||||
|
AttachmentData {
|
||||||
|
colors: self.colors.iter().map(&fun).collect(),
|
||||||
|
resolves: self.resolves.iter().map(&fun).collect(),
|
||||||
|
depth_stencil: self.depth_stencil.as_ref().map(&fun),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) type AttachmentDataVec<T> = ArrayVec<[T; MAX_COLOR_TARGETS + MAX_COLOR_TARGETS + 1]>;
|
pub(crate) type AttachmentDataVec<T> = ArrayVec<[T; MAX_COLOR_TARGETS + MAX_COLOR_TARGETS + 1]>;
|
||||||
|
|
||||||
pub(crate) type RenderPassKey = AttachmentData<(hal::pass::Attachment, hal::image::Layout)>;
|
pub(crate) type RenderPassKey = AttachmentData<(hal::pass::Attachment, hal::image::Layout)>;
|
||||||
pub(crate) type FramebufferKey = AttachmentData<id::Valid<id::TextureViewId>>;
|
pub(crate) type FramebufferKey = AttachmentData<hal::image::FramebufferAttachment>;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Hash, PartialEq)]
|
#[derive(Clone, Debug, Hash, PartialEq)]
|
||||||
#[cfg_attr(feature = "serial-pass", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "serial-pass", derive(serde::Deserialize, serde::Serialize))]
|
||||||
@ -211,11 +219,17 @@ fn fire_map_callbacks<I: IntoIterator<Item = BufferMapPendingCallback>>(callback
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct RenderPassLock<B: hal::Backend> {
|
||||||
|
pub(crate) render_passes: FastHashMap<RenderPassKey, B::RenderPass>,
|
||||||
|
pub(crate) framebuffers: FastHashMap<FramebufferKey, B::Framebuffer>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Structure describing a logical device. Some members are internally mutable,
|
/// Structure describing a logical device. Some members are internally mutable,
|
||||||
/// stored behind mutexes.
|
/// stored behind mutexes.
|
||||||
/// TODO: establish clear order of locking for these:
|
/// TODO: establish clear order of locking for these:
|
||||||
/// `mem_allocator`, `desc_allocator`, `life_tracke`, `trackers`,
|
/// `mem_allocator`, `desc_allocator`, `life_tracke`, `trackers`,
|
||||||
/// `render_passes`, `framebuffers`, `pending_writes`, `trace`.
|
/// `render_passes`, `pending_writes`, `trace`.
|
||||||
///
|
///
|
||||||
/// Currently, the rules are:
|
/// Currently, the rules are:
|
||||||
/// 1. `life_tracker` is locked after `hub.devices`, enforced by the type system
|
/// 1. `life_tracker` is locked after `hub.devices`, enforced by the type system
|
||||||
@ -234,8 +248,7 @@ pub struct Device<B: hal::Backend> {
|
|||||||
pub(crate) active_submission_index: SubmissionIndex,
|
pub(crate) active_submission_index: SubmissionIndex,
|
||||||
/// Has to be locked temporarily only (locked last)
|
/// Has to be locked temporarily only (locked last)
|
||||||
pub(crate) trackers: Mutex<TrackerSet>,
|
pub(crate) trackers: Mutex<TrackerSet>,
|
||||||
pub(crate) render_passes: Mutex<FastHashMap<RenderPassKey, B::RenderPass>>,
|
pub(crate) render_passes: Mutex<RenderPassLock<B>>,
|
||||||
pub(crate) framebuffers: Mutex<FastHashMap<FramebufferKey, B::Framebuffer>>,
|
|
||||||
// Life tracker should be locked right after the device and before anything else.
|
// Life tracker should be locked right after the device and before anything else.
|
||||||
life_tracker: Mutex<life::LifetimeTracker<B>>,
|
life_tracker: Mutex<life::LifetimeTracker<B>>,
|
||||||
temp_suspected: life::SuspectedResources,
|
temp_suspected: life::SuspectedResources,
|
||||||
@ -297,8 +310,10 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
life_guard: LifeGuard::new("<device>"),
|
life_guard: LifeGuard::new("<device>"),
|
||||||
active_submission_index: 0,
|
active_submission_index: 0,
|
||||||
trackers: Mutex::new(TrackerSet::new(B::VARIANT)),
|
trackers: Mutex::new(TrackerSet::new(B::VARIANT)),
|
||||||
render_passes: Mutex::new(FastHashMap::default()),
|
render_passes: Mutex::new(RenderPassLock {
|
||||||
framebuffers: Mutex::new(FastHashMap::default()),
|
render_passes: FastHashMap::default(),
|
||||||
|
framebuffers: FastHashMap::default(),
|
||||||
|
}),
|
||||||
life_tracker: Mutex::new(life::LifetimeTracker::new()),
|
life_tracker: Mutex::new(life::LifetimeTracker::new()),
|
||||||
temp_suspected: life::SuspectedResources::default(),
|
temp_suspected: life::SuspectedResources::default(),
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "trace")]
|
||||||
@ -359,7 +374,6 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
token,
|
token,
|
||||||
);
|
);
|
||||||
life_tracker.triage_mapped(hub, token);
|
life_tracker.triage_mapped(hub, token);
|
||||||
life_tracker.triage_framebuffers(hub, &mut *self.framebuffers.lock(), token);
|
|
||||||
let last_done = life_tracker.triage_submissions(&self.raw, force_wait)?;
|
let last_done = life_tracker.triage_submissions(&self.raw, force_wait)?;
|
||||||
let callbacks = life_tracker.handle_mapping(hub, &self.raw, &self.trackers, token);
|
let callbacks = life_tracker.handle_mapping(hub, &self.raw, &self.trackers, token);
|
||||||
life_tracker.cleanup(&self.raw, &self.mem_allocator, &self.desc_allocator);
|
life_tracker.cleanup(&self.raw, &self.mem_allocator, &self.desc_allocator);
|
||||||
@ -591,12 +605,11 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
mip_level_count,
|
mip_level_count,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let mut view_capabilities = hal::image::ViewCapabilities::empty();
|
let mut view_caps = hal::image::ViewCapabilities::empty();
|
||||||
|
|
||||||
// 2D textures with array layer counts that are multiples of 6 could be cubemaps
|
// 2D textures with array layer counts that are multiples of 6 could be cubemaps
|
||||||
// Following gpuweb/gpuweb#68 always add the hint in that case
|
// Following gpuweb/gpuweb#68 always add the hint in that case
|
||||||
if desc.dimension == TextureDimension::D2 && desc.size.depth % 6 == 0 {
|
if desc.dimension == TextureDimension::D2 && desc.size.depth % 6 == 0 {
|
||||||
view_capabilities |= hal::image::ViewCapabilities::KIND_CUBE;
|
view_caps |= hal::image::ViewCapabilities::KIND_CUBE;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: 2D arrays, cubemap arrays
|
// TODO: 2D arrays, cubemap arrays
|
||||||
@ -610,7 +623,7 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
format,
|
format,
|
||||||
hal::image::Tiling::Optimal,
|
hal::image::Tiling::Optimal,
|
||||||
usage,
|
usage,
|
||||||
view_capabilities,
|
view_caps,
|
||||||
)
|
)
|
||||||
.map_err(|err| match err {
|
.map_err(|err| match err {
|
||||||
hal::image::CreationError::OutOfMemory(_) => DeviceError::OutOfMemory,
|
hal::image::CreationError::OutOfMemory(_) => DeviceError::OutOfMemory,
|
||||||
@ -642,6 +655,11 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
kind,
|
kind,
|
||||||
format: desc.format,
|
format: desc.format,
|
||||||
format_features,
|
format_features,
|
||||||
|
framebuffer_attachment: hal::image::FramebufferAttachment {
|
||||||
|
usage,
|
||||||
|
format,
|
||||||
|
view_caps,
|
||||||
|
},
|
||||||
full_range: TextureSelector {
|
full_range: TextureSelector {
|
||||||
levels: 0..desc.mip_level_count as hal::image::Level,
|
levels: 0..desc.mip_level_count as hal::image::Level,
|
||||||
layers: 0..kind.num_layers(),
|
layers: 0..kind.num_layers(),
|
||||||
@ -801,6 +819,7 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
format_features: texture.format_features,
|
format_features: texture.format_features,
|
||||||
extent: texture.kind.extent().at_level(desc.base_mip_level as _),
|
extent: texture.kind.extent().at_level(desc.base_mip_level as _),
|
||||||
samples: texture.kind.num_samples(),
|
samples: texture.kind.num_samples(),
|
||||||
|
framebuffer_attachment: texture.framebuffer_attachment.clone(),
|
||||||
selector,
|
selector,
|
||||||
life_guard: LifeGuard::new(desc.label.borrow_or_default()),
|
life_guard: LifeGuard::new(desc.label.borrow_or_default()),
|
||||||
})
|
})
|
||||||
@ -2172,7 +2191,7 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
.get(pipeline_layout_id)
|
.get(pipeline_layout_id)
|
||||||
.map_err(|_| pipeline::CreateRenderPipelineError::InvalidLayout)?;
|
.map_err(|_| pipeline::CreateRenderPipelineError::InvalidLayout)?;
|
||||||
|
|
||||||
let mut render_pass_cache = self.render_passes.lock();
|
let mut rp_lock = self.render_passes.lock();
|
||||||
let pipeline_desc = hal::pso::GraphicsPipelineDesc {
|
let pipeline_desc = hal::pso::GraphicsPipelineDesc {
|
||||||
label: desc.label.as_ref().map(AsRef::as_ref),
|
label: desc.label.as_ref().map(AsRef::as_ref),
|
||||||
primitive_assembler,
|
primitive_assembler,
|
||||||
@ -2185,7 +2204,7 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
layout: &layout.raw,
|
layout: &layout.raw,
|
||||||
subpass: hal::pass::Subpass {
|
subpass: hal::pass::Subpass {
|
||||||
index: 0,
|
index: 0,
|
||||||
main_pass: match render_pass_cache.entry(rp_key) {
|
main_pass: match rp_lock.render_passes.entry(rp_key) {
|
||||||
Entry::Occupied(e) => e.into_mut(),
|
Entry::Occupied(e) => e.into_mut(),
|
||||||
Entry::Vacant(e) => {
|
Entry::Vacant(e) => {
|
||||||
let pass = self
|
let pass = self
|
||||||
@ -2312,10 +2331,11 @@ impl<B: hal::Backend> Device<B> {
|
|||||||
unsafe {
|
unsafe {
|
||||||
desc_alloc.cleanup(&self.raw);
|
desc_alloc.cleanup(&self.raw);
|
||||||
mem_alloc.clear(&self.raw);
|
mem_alloc.clear(&self.raw);
|
||||||
for (_, rp) in self.render_passes.lock().drain() {
|
let rps = self.render_passes.into_inner();
|
||||||
|
for (_, rp) in rps.render_passes {
|
||||||
self.raw.destroy_render_pass(rp);
|
self.raw.destroy_render_pass(rp);
|
||||||
}
|
}
|
||||||
for (_, fbo) in self.framebuffers.lock().drain() {
|
for (_, fbo) in rps.framebuffers {
|
||||||
self.raw.destroy_framebuffer(fbo);
|
self.raw.destroy_framebuffer(fbo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3987,6 +4007,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
validate_swap_chain_descriptor(&mut config, &caps)?;
|
validate_swap_chain_descriptor(&mut config, &caps)?;
|
||||||
|
let framebuffer_attachment = config.framebuffer_attachment();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
B::get_surface_mut(surface)
|
B::get_surface_mut(surface)
|
||||||
@ -4027,8 +4048,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
.create_semaphore()
|
.create_semaphore()
|
||||||
.or(Err(DeviceError::OutOfMemory))?,
|
.or(Err(DeviceError::OutOfMemory))?,
|
||||||
acquired_view_id: None,
|
acquired_view_id: None,
|
||||||
acquired_framebuffers: Vec::new(),
|
|
||||||
active_submission_index: 0,
|
active_submission_index: 0,
|
||||||
|
framebuffer_attachment,
|
||||||
};
|
};
|
||||||
swap_chain_guard.insert(sc_id, swap_chain);
|
swap_chain_guard.insert(sc_id, swap_chain);
|
||||||
Ok(sc_id)
|
Ok(sc_id)
|
||||||
|
|||||||
@ -514,19 +514,17 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (sc_id, fbo) in cmdbuf.used_swap_chains.drain(..) {
|
for sc_id in cmdbuf.used_swap_chains.drain(..) {
|
||||||
let sc = &mut swap_chain_guard[sc_id.value];
|
let sc = &mut swap_chain_guard[sc_id.value];
|
||||||
sc.active_submission_index = submit_index;
|
|
||||||
if sc.acquired_view_id.is_none() {
|
if sc.acquired_view_id.is_none() {
|
||||||
return Err(QueueSubmitError::SwapChainOutputDropped);
|
return Err(QueueSubmitError::SwapChainOutputDropped);
|
||||||
}
|
}
|
||||||
// For each swapchain, we only want to have at most 1 signaled semaphore.
|
if sc.active_submission_index != submit_index {
|
||||||
if sc.acquired_framebuffers.is_empty() {
|
sc.active_submission_index = submit_index;
|
||||||
// Only add a signal if this is the first time for this swapchain
|
// Only add a signal if this is the first time for this swapchain
|
||||||
// to be used in the submission.
|
// to be used in the submission.
|
||||||
signal_swapchain_semaphores.push(sc_id.value);
|
signal_swapchain_semaphores.push(sc_id.value);
|
||||||
}
|
}
|
||||||
sc.acquired_framebuffers.push(fbo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// optimize the tracked states
|
// optimize the tracked states
|
||||||
|
|||||||
@ -206,6 +206,7 @@ pub struct Texture<B: hal::Backend> {
|
|||||||
pub(crate) kind: hal::image::Kind,
|
pub(crate) kind: hal::image::Kind,
|
||||||
pub(crate) format: wgt::TextureFormat,
|
pub(crate) format: wgt::TextureFormat,
|
||||||
pub(crate) format_features: wgt::TextureFormatFeatures,
|
pub(crate) format_features: wgt::TextureFormatFeatures,
|
||||||
|
pub(crate) framebuffer_attachment: hal::image::FramebufferAttachment,
|
||||||
pub(crate) full_range: TextureSelector,
|
pub(crate) full_range: TextureSelector,
|
||||||
pub(crate) life_guard: LifeGuard,
|
pub(crate) life_guard: LifeGuard,
|
||||||
}
|
}
|
||||||
@ -309,6 +310,7 @@ pub struct TextureView<B: hal::Backend> {
|
|||||||
pub(crate) format_features: wgt::TextureFormatFeatures,
|
pub(crate) format_features: wgt::TextureFormatFeatures,
|
||||||
pub(crate) extent: hal::image::Extent,
|
pub(crate) extent: hal::image::Extent,
|
||||||
pub(crate) samples: hal::image::NumSamples,
|
pub(crate) samples: hal::image::NumSamples,
|
||||||
|
pub(crate) framebuffer_attachment: hal::image::FramebufferAttachment,
|
||||||
pub(crate) selector: TextureSelector,
|
pub(crate) selector: TextureSelector,
|
||||||
pub(crate) life_guard: LifeGuard,
|
pub(crate) life_guard: LifeGuard,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,7 +44,7 @@ use crate::{
|
|||||||
LifeGuard, PrivateFeatures, Stored, SubmissionIndex,
|
LifeGuard, PrivateFeatures, Stored, SubmissionIndex,
|
||||||
};
|
};
|
||||||
|
|
||||||
use hal::{self, device::Device as _, queue::CommandQueue as _, window::PresentationSurface as _};
|
use hal::{queue::CommandQueue as _, window::PresentationSurface as _};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use wgt::{SwapChainDescriptor, SwapChainStatus};
|
use wgt::{SwapChainDescriptor, SwapChainStatus};
|
||||||
|
|
||||||
@ -59,8 +59,8 @@ pub struct SwapChain<B: hal::Backend> {
|
|||||||
pub(crate) num_frames: hal::window::SwapImageIndex,
|
pub(crate) num_frames: hal::window::SwapImageIndex,
|
||||||
pub(crate) semaphore: B::Semaphore,
|
pub(crate) semaphore: B::Semaphore,
|
||||||
pub(crate) acquired_view_id: Option<Stored<TextureViewId>>,
|
pub(crate) acquired_view_id: Option<Stored<TextureViewId>>,
|
||||||
pub(crate) acquired_framebuffers: Vec<B::Framebuffer>,
|
|
||||||
pub(crate) active_submission_index: SubmissionIndex,
|
pub(crate) active_submission_index: SubmissionIndex,
|
||||||
|
pub(crate) framebuffer_attachment: hal::image::FramebufferAttachment,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: hal::Backend> crate::hub::Resource for SwapChain<B> {
|
impl<B: hal::Backend> crate::hub::Resource for SwapChain<B> {
|
||||||
@ -194,6 +194,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
depth: 1,
|
depth: 1,
|
||||||
},
|
},
|
||||||
samples: 1,
|
samples: 1,
|
||||||
|
framebuffer_attachment: sc.framebuffer_attachment.clone(),
|
||||||
selector: TextureSelector {
|
selector: TextureSelector {
|
||||||
layers: 0..1,
|
layers: 0..1,
|
||||||
levels: 0..1,
|
levels: 0..1,
|
||||||
@ -282,12 +283,6 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
|
|
||||||
tracing::debug!(trace = true, "Presented. End of Frame");
|
tracing::debug!(trace = true, "Presented. End of Frame");
|
||||||
|
|
||||||
for fbo in sc.acquired_framebuffers.drain(..) {
|
|
||||||
unsafe {
|
|
||||||
device.raw.destroy_framebuffer(fbo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(None) => Ok(SwapChainStatus::Good),
|
Ok(None) => Ok(SwapChainStatus::Good),
|
||||||
Ok(Some(_)) => Ok(SwapChainStatus::Suboptimal),
|
Ok(Some(_)) => Ok(SwapChainStatus::Suboptimal),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user