mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-26 00:33:51 +00:00
Merge #744
744: Add `backends!` and `backends_map!` macros to code duplication r=kvark a=Kimundi **Description** The source code is doing a lot of things duplicated for each backend, which leads to code duplication and harder to read code. This PR attempts to improve the situation by introducing a `backends!` and `backends_map!` for doing the code duplication automatically. **Testing** The macro have unit tests for checking that they work correctly. Co-authored-by: Marvin Löbel <loebel.marvin@gmail.com>
This commit is contained in:
commit
29e286bdc1
@ -2734,17 +2734,20 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
use crate::backend;
|
||||
let mut callbacks = Vec::new();
|
||||
|
||||
#[cfg(any(
|
||||
not(any(target_os = "ios", target_os = "macos")),
|
||||
feature = "gfx-backend-vulkan"
|
||||
))]
|
||||
self.poll_devices::<backend::Vulkan>(force_wait, &mut callbacks);
|
||||
#[cfg(windows)]
|
||||
self.poll_devices::<backend::Dx11>(force_wait, &mut callbacks);
|
||||
#[cfg(windows)]
|
||||
self.poll_devices::<backend::Dx12>(force_wait, &mut callbacks);
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
self.poll_devices::<backend::Metal>(force_wait, &mut callbacks);
|
||||
backends! {
|
||||
#[vulkan] {
|
||||
self.poll_devices::<backend::Vulkan>(force_wait, &mut callbacks);
|
||||
}
|
||||
#[metal] {
|
||||
self.poll_devices::<backend::Metal>(force_wait, &mut callbacks);
|
||||
}
|
||||
#[dx12] {
|
||||
self.poll_devices::<backend::Dx12>(force_wait, &mut callbacks);
|
||||
}
|
||||
#[dx11] {
|
||||
self.poll_devices::<backend::Dx11>(force_wait, &mut callbacks);
|
||||
}
|
||||
}
|
||||
|
||||
fire_map_callbacks(callbacks);
|
||||
}
|
||||
|
@ -553,18 +553,17 @@ pub struct Hubs<F: GlobalIdentityHandlerFactory> {
|
||||
|
||||
impl<F: GlobalIdentityHandlerFactory> Hubs<F> {
|
||||
fn new(factory: &F) -> Self {
|
||||
Hubs {
|
||||
#[cfg(any(
|
||||
not(any(target_os = "ios", target_os = "macos")),
|
||||
feature = "gfx-backend-vulkan"
|
||||
))]
|
||||
vulkan: Hub::new(factory),
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
metal: Hub::new(factory),
|
||||
#[cfg(windows)]
|
||||
dx12: Hub::new(factory),
|
||||
#[cfg(windows)]
|
||||
dx11: Hub::new(factory),
|
||||
backends! {
|
||||
Hubs {
|
||||
#[vulkan]
|
||||
vulkan: Hub::new(factory),
|
||||
#[metal]
|
||||
metal: Hub::new(factory),
|
||||
#[dx12]
|
||||
dx12: Hub::new(factory),
|
||||
#[dx11]
|
||||
dx11: Hub::new(factory),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -592,18 +591,23 @@ impl<G: GlobalIdentityHandlerFactory> Drop for Global<G> {
|
||||
if !thread::panicking() {
|
||||
log::info!("Dropping Global");
|
||||
let mut surface_guard = self.surfaces.data.write();
|
||||
|
||||
// destroy hubs
|
||||
#[cfg(any(
|
||||
not(any(target_os = "ios", target_os = "macos")),
|
||||
feature = "gfx-backend-vulkan"
|
||||
))]
|
||||
self.hubs.vulkan.clear(&mut *surface_guard);
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
self.hubs.metal.clear(&mut *surface_guard);
|
||||
#[cfg(windows)]
|
||||
self.hubs.dx12.clear(&mut *surface_guard);
|
||||
#[cfg(windows)]
|
||||
self.hubs.dx11.clear(&mut *surface_guard);
|
||||
backends! {
|
||||
#[vulkan] {
|
||||
self.hubs.vulkan.clear(&mut *surface_guard);
|
||||
}
|
||||
#[metal] {
|
||||
self.hubs.metal.clear(&mut *surface_guard);
|
||||
}
|
||||
#[dx12] {
|
||||
self.hubs.dx12.clear(&mut *surface_guard);
|
||||
}
|
||||
#[dx11] {
|
||||
self.hubs.dx11.clear(&mut *surface_guard);
|
||||
}
|
||||
}
|
||||
|
||||
// destroy surfaces
|
||||
for (_, (surface, _)) in surface_guard.map.drain() {
|
||||
self.instance.destroy_surface(surface);
|
||||
|
@ -59,61 +59,45 @@ pub struct Instance {
|
||||
|
||||
impl Instance {
|
||||
pub fn new(name: &str, version: u32, backends: BackendBit) -> Self {
|
||||
Instance {
|
||||
#[cfg(any(
|
||||
not(any(target_os = "ios", target_os = "macos")),
|
||||
feature = "gfx-backend-vulkan"
|
||||
))]
|
||||
vulkan: if backends.contains(Backend::Vulkan.into()) {
|
||||
gfx_backend_vulkan::Instance::create(name, version).ok()
|
||||
} else {
|
||||
None
|
||||
},
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
metal: if backends.contains(Backend::Metal.into()) {
|
||||
Some(gfx_backend_metal::Instance::create(name, version).unwrap())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
#[cfg(windows)]
|
||||
dx12: if backends.contains(Backend::Dx12.into()) {
|
||||
gfx_backend_dx12::Instance::create(name, version).ok()
|
||||
} else {
|
||||
None
|
||||
},
|
||||
#[cfg(windows)]
|
||||
dx11: if backends.contains(Backend::Dx11.into()) {
|
||||
Some(gfx_backend_dx11::Instance::create(name, version).unwrap())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
backends_map! {
|
||||
let map = |(backend, backend_create)| {
|
||||
if backends.contains(backend.into()) {
|
||||
backend_create(name, version).ok()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
Instance {
|
||||
#[vulkan]
|
||||
vulkan: map((Backend::Vulkan, gfx_backend_vulkan::Instance::create)),
|
||||
#[metal]
|
||||
metal: map((Backend::Metal, gfx_backend_metal::Instance::create)),
|
||||
#[dx12]
|
||||
dx12: map((Backend::Dx12, gfx_backend_dx12::Instance::create)),
|
||||
#[dx11]
|
||||
dx11: map((Backend::Dx11, gfx_backend_dx11::Instance::create)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn destroy_surface(&mut self, surface: Surface) {
|
||||
#[cfg(any(
|
||||
not(any(target_os = "ios", target_os = "macos")),
|
||||
feature = "gfx-backend-vulkan"
|
||||
))]
|
||||
unsafe {
|
||||
if let Some(suf) = surface.vulkan {
|
||||
self.vulkan.as_mut().unwrap().destroy_surface(suf);
|
||||
}
|
||||
}
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
unsafe {
|
||||
if let Some(suf) = surface.metal {
|
||||
self.metal.as_mut().unwrap().destroy_surface(suf);
|
||||
}
|
||||
}
|
||||
#[cfg(windows)]
|
||||
unsafe {
|
||||
if let Some(suf) = surface.dx12 {
|
||||
self.dx12.as_mut().unwrap().destroy_surface(suf);
|
||||
}
|
||||
if let Some(suf) = surface.dx11 {
|
||||
self.dx11.as_mut().unwrap().destroy_surface(suf);
|
||||
}
|
||||
backends_map! {
|
||||
let map = |(surface_backend, self_backend)| {
|
||||
unsafe {
|
||||
if let Some(suf) = surface_backend {
|
||||
self_backend.as_mut().unwrap().destroy_surface(suf);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#[vulkan]
|
||||
map((surface.vulkan, &mut self.vulkan)),
|
||||
#[metal]
|
||||
map((surface.metal, &mut self.metal)),
|
||||
#[dx12]
|
||||
map((surface.dx12, &mut self.dx12)),
|
||||
#[dx11]
|
||||
map((surface.dx11, &mut self.dx11)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -300,35 +284,23 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
span!(_guard, INFO, "Instance::create_surface");
|
||||
|
||||
let surface = unsafe {
|
||||
Surface {
|
||||
#[cfg(any(
|
||||
windows,
|
||||
all(unix, not(any(target_os = "ios", target_os = "macos"))),
|
||||
feature = "gfx-backend-vulkan",
|
||||
))]
|
||||
vulkan: self
|
||||
.instance
|
||||
.vulkan
|
||||
backends_map! {
|
||||
let map = |inst| {
|
||||
inst
|
||||
.as_ref()
|
||||
.and_then(|inst| inst.create_surface(handle).ok()),
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
metal: self
|
||||
.instance
|
||||
.metal
|
||||
.as_ref()
|
||||
.and_then(|inst| inst.create_surface(handle).ok()),
|
||||
#[cfg(windows)]
|
||||
dx12: self
|
||||
.instance
|
||||
.dx12
|
||||
.as_ref()
|
||||
.and_then(|inst| inst.create_surface(handle).ok()),
|
||||
#[cfg(windows)]
|
||||
dx11: self
|
||||
.instance
|
||||
.dx11
|
||||
.as_ref()
|
||||
.and_then(|inst| inst.create_surface(handle).ok()),
|
||||
.and_then(|inst| inst.create_surface(handle).ok())
|
||||
};
|
||||
|
||||
Surface {
|
||||
#[vulkan]
|
||||
vulkan: map(&self.instance.vulkan),
|
||||
#[metal]
|
||||
metal: map(&self.instance.metal),
|
||||
#[dx12]
|
||||
dx12: map(&self.instance.dx12),
|
||||
#[dx11]
|
||||
dx11: map(&self.instance.dx11),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -347,69 +319,31 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
let mut token = Token::root();
|
||||
let mut adapters = Vec::new();
|
||||
|
||||
#[cfg(any(
|
||||
not(any(target_os = "ios", target_os = "macos")),
|
||||
feature = "gfx-backend-vulkan"
|
||||
))]
|
||||
{
|
||||
if let Some(ref inst) = instance.vulkan {
|
||||
if let Some(id_vulkan) = inputs.find(Backend::Vulkan) {
|
||||
for raw in inst.enumerate_adapters() {
|
||||
let adapter = Adapter::new(raw, unsafe_extensions);
|
||||
log::info!("Adapter Vulkan {:?}", adapter.raw.info);
|
||||
adapters.push(backend::Vulkan::hub(self).adapters.register_identity(
|
||||
id_vulkan.clone(),
|
||||
adapter,
|
||||
&mut token,
|
||||
));
|
||||
backends_map! {
|
||||
let map = |(instance_field, backend, backend_info, backend_hub)| {
|
||||
if let Some(inst) = instance_field {
|
||||
if let Some(id_backend) = inputs.find(backend) {
|
||||
for raw in inst.enumerate_adapters() {
|
||||
let adapter = Adapter::new(raw, unsafe_extensions);
|
||||
log::info!("Adapter {} {:?}", backend_info, adapter.raw.info);
|
||||
adapters.push(backend_hub(self).adapters.register_identity(
|
||||
id_backend.clone(),
|
||||
adapter,
|
||||
&mut token,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
{
|
||||
if let Some(ref inst) = instance.metal {
|
||||
if let Some(id_metal) = inputs.find(Backend::Metal) {
|
||||
for raw in inst.enumerate_adapters() {
|
||||
let adapter = Adapter::new(raw, unsafe_extensions);
|
||||
log::info!("Adapter Metal {:?}", adapter.raw.info);
|
||||
adapters.push(backend::Metal::hub(self).adapters.register_identity(
|
||||
id_metal.clone(),
|
||||
adapter,
|
||||
&mut token,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(windows)]
|
||||
{
|
||||
if let Some(ref inst) = instance.dx12 {
|
||||
if let Some(id_dx12) = inputs.find(Backend::Dx12) {
|
||||
for raw in inst.enumerate_adapters() {
|
||||
let adapter = Adapter::new(raw, unsafe_extensions);
|
||||
log::info!("Adapter Dx12 {:?}", adapter.raw.info);
|
||||
adapters.push(backend::Dx12::hub(self).adapters.register_identity(
|
||||
id_dx12.clone(),
|
||||
adapter,
|
||||
&mut token,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(ref inst) = instance.dx11 {
|
||||
if let Some(id_dx11) = inputs.find(Backend::Dx11) {
|
||||
for raw in inst.enumerate_adapters() {
|
||||
let adapter = Adapter::new(raw, unsafe_extensions);
|
||||
log::info!("Adapter Dx11 {:?}", adapter.raw.info);
|
||||
adapters.push(backend::Dx11::hub(self).adapters.register_identity(
|
||||
id_dx11.clone(),
|
||||
adapter,
|
||||
&mut token,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#[vulkan]
|
||||
map((&instance.vulkan, Backend::Vulkan, "Vulkan", backend::Vulkan::hub)),
|
||||
#[metal]
|
||||
map((&instance.metal, Backend::Metal, "Metal", backend::Metal::hub)),
|
||||
#[dx12]
|
||||
map((&instance.dx12, Backend::Dx12, "Dx12", backend::Dx12::hub)),
|
||||
#[dx11]
|
||||
map((&instance.dx11, Backend::Dx11, "Dx11", backend::Dx11::hub)),
|
||||
}
|
||||
|
||||
adapters
|
||||
@ -429,98 +363,62 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
let compatible_surface = desc.compatible_surface.map(|id| &surface_guard[id]);
|
||||
let mut device_types = Vec::new();
|
||||
|
||||
let id_vulkan = inputs.find(Backend::Vulkan);
|
||||
let id_metal = inputs.find(Backend::Metal);
|
||||
let id_dx12 = inputs.find(Backend::Dx12);
|
||||
let id_dx11 = inputs.find(Backend::Dx11);
|
||||
let mut id_vulkan = inputs.find(Backend::Vulkan);
|
||||
let mut id_metal = inputs.find(Backend::Metal);
|
||||
let mut id_dx12 = inputs.find(Backend::Dx12);
|
||||
let mut id_dx11 = inputs.find(Backend::Dx11);
|
||||
|
||||
#[cfg(any(
|
||||
not(any(target_os = "ios", target_os = "macos")),
|
||||
feature = "gfx-backend-vulkan"
|
||||
))]
|
||||
let mut adapters_vk = match instance.vulkan {
|
||||
Some(ref inst) if id_vulkan.is_some() => {
|
||||
let mut adapters = inst.enumerate_adapters();
|
||||
if let Some(&Surface {
|
||||
vulkan: Some(ref surface),
|
||||
..
|
||||
}) = compatible_surface
|
||||
{
|
||||
adapters.retain(|a| {
|
||||
a.queue_families
|
||||
.iter()
|
||||
.find(|qf| qf.queue_type().supports_graphics())
|
||||
.map_or(false, |qf| surface.supports_queue_family(qf))
|
||||
});
|
||||
backends_map! {
|
||||
let map = |(instance_backend, id_backend, surface_backend)| {
|
||||
match instance_backend {
|
||||
Some(ref inst) if id_backend.is_some() => {
|
||||
let mut adapters = inst.enumerate_adapters();
|
||||
if let Some(surface_backend) = compatible_surface.and_then(surface_backend) {
|
||||
adapters.retain(|a| {
|
||||
a.queue_families
|
||||
.iter()
|
||||
.find(|qf| qf.queue_type().supports_graphics())
|
||||
.map_or(false, |qf| surface_backend.supports_queue_family(qf))
|
||||
});
|
||||
}
|
||||
device_types.extend(adapters.iter().map(|ad| ad.info.device_type.clone()));
|
||||
adapters
|
||||
}
|
||||
_ => Vec::new(),
|
||||
}
|
||||
device_types.extend(adapters.iter().map(|ad| ad.info.device_type.clone()));
|
||||
adapters
|
||||
}
|
||||
_ => Vec::new(),
|
||||
};
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
let mut adapters_mtl = match instance.metal {
|
||||
Some(ref inst) if id_metal.is_some() => {
|
||||
let mut adapters = inst.enumerate_adapters();
|
||||
if let Some(&Surface {
|
||||
metal: Some(ref surface),
|
||||
..
|
||||
}) = compatible_surface
|
||||
{
|
||||
adapters.retain(|a| {
|
||||
a.queue_families
|
||||
.iter()
|
||||
.find(|qf| qf.queue_type().supports_graphics())
|
||||
.map_or(false, |qf| surface.supports_queue_family(qf))
|
||||
});
|
||||
};
|
||||
|
||||
// NB: The internal function definitions are a workaround for Rust
|
||||
// being weird with lifetimes for closure literals...
|
||||
#[vulkan]
|
||||
let adapters_vk = map((&instance.vulkan, &id_vulkan, {
|
||||
fn surface_vulkan(surf: &Surface) -> Option<&GfxSurface<backend::Vulkan>> {
|
||||
surf.vulkan.as_ref()
|
||||
}
|
||||
device_types.extend(adapters.iter().map(|ad| ad.info.device_type.clone()));
|
||||
adapters
|
||||
}
|
||||
_ => Vec::new(),
|
||||
};
|
||||
#[cfg(windows)]
|
||||
let mut adapters_dx12 = match instance.dx12 {
|
||||
Some(ref inst) if id_dx12.is_some() => {
|
||||
let mut adapters = inst.enumerate_adapters();
|
||||
if let Some(&Surface {
|
||||
dx12: Some(ref surface),
|
||||
..
|
||||
}) = compatible_surface
|
||||
{
|
||||
adapters.retain(|a| {
|
||||
a.queue_families
|
||||
.iter()
|
||||
.find(|qf| qf.queue_type().supports_graphics())
|
||||
.map_or(false, |qf| surface.supports_queue_family(qf))
|
||||
});
|
||||
surface_vulkan
|
||||
}));
|
||||
#[metal]
|
||||
let adapters_mtl = map((&instance.metal, &id_metal, {
|
||||
fn surface_metal(surf: &Surface) -> Option<&GfxSurface<backend::Metal>> {
|
||||
surf.metal.as_ref()
|
||||
}
|
||||
device_types.extend(adapters.iter().map(|ad| ad.info.device_type.clone()));
|
||||
adapters
|
||||
}
|
||||
_ => Vec::new(),
|
||||
};
|
||||
#[cfg(windows)]
|
||||
let mut adapters_dx11 = match instance.dx11 {
|
||||
Some(ref inst) if id_dx11.is_some() => {
|
||||
let mut adapters = inst.enumerate_adapters();
|
||||
if let Some(&Surface {
|
||||
dx11: Some(ref surface),
|
||||
..
|
||||
}) = compatible_surface
|
||||
{
|
||||
adapters.retain(|a| {
|
||||
a.queue_families
|
||||
.iter()
|
||||
.find(|qf| qf.queue_type().supports_graphics())
|
||||
.map_or(false, |qf| surface.supports_queue_family(qf))
|
||||
});
|
||||
surface_metal
|
||||
}));
|
||||
#[dx12]
|
||||
let adapters_dx12 = map((&instance.dx12, &id_dx12, {
|
||||
fn surface_dx12(surf: &Surface) -> Option<&GfxSurface<backend::Dx12>> {
|
||||
surf.dx12.as_ref()
|
||||
}
|
||||
device_types.extend(adapters.iter().map(|ad| ad.info.device_type.clone()));
|
||||
adapters
|
||||
}
|
||||
_ => Vec::new(),
|
||||
};
|
||||
surface_dx12
|
||||
}));
|
||||
#[dx11]
|
||||
let adapters_dx11 = map((&instance.dx11, &id_dx11, {
|
||||
fn surface_dx11(surf: &Surface) -> Option<&GfxSurface<backend::Dx11>> {
|
||||
surf.dx11.as_ref()
|
||||
}
|
||||
surface_dx11
|
||||
}));
|
||||
}
|
||||
|
||||
if device_types.is_empty() {
|
||||
log::warn!("No adapters are available!");
|
||||
@ -563,64 +461,39 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
};
|
||||
|
||||
let mut selected = preferred_gpu.unwrap_or(0);
|
||||
#[cfg(any(
|
||||
not(any(target_os = "ios", target_os = "macos")),
|
||||
feature = "gfx-backend-vulkan"
|
||||
))]
|
||||
{
|
||||
if selected < adapters_vk.len() {
|
||||
let adapter = Adapter::new(adapters_vk.swap_remove(selected), unsafe_extensions);
|
||||
log::info!("Adapter Vulkan {:?}", adapter.raw.info);
|
||||
let id = backend::Vulkan::hub(self).adapters.register_identity(
|
||||
id_vulkan.unwrap(),
|
||||
adapter,
|
||||
&mut token,
|
||||
);
|
||||
return Some(id);
|
||||
}
|
||||
selected -= adapters_vk.len();
|
||||
}
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
{
|
||||
if selected < adapters_mtl.len() {
|
||||
let adapter = Adapter::new(adapters_mtl.swap_remove(selected), unsafe_extensions);
|
||||
log::info!("Adapter Metal {:?}", adapter.raw.info);
|
||||
let id = backend::Metal::hub(self).adapters.register_identity(
|
||||
id_metal.unwrap(),
|
||||
adapter,
|
||||
&mut token,
|
||||
);
|
||||
return Some(id);
|
||||
}
|
||||
selected -= adapters_mtl.len();
|
||||
}
|
||||
#[cfg(windows)]
|
||||
{
|
||||
if selected < adapters_dx12.len() {
|
||||
let adapter = Adapter::new(adapters_dx12.swap_remove(selected), unsafe_extensions);
|
||||
log::info!("Adapter Dx12 {:?}", adapter.raw.info);
|
||||
let id = backend::Dx12::hub(self).adapters.register_identity(
|
||||
id_dx12.unwrap(),
|
||||
adapter,
|
||||
&mut token,
|
||||
);
|
||||
return Some(id);
|
||||
}
|
||||
selected -= adapters_dx12.len();
|
||||
if selected < adapters_dx11.len() {
|
||||
let adapter = Adapter::new(adapters_dx11.swap_remove(selected), unsafe_extensions);
|
||||
log::info!("Adapter Dx11 {:?}", adapter.raw.info);
|
||||
let id = backend::Dx11::hub(self).adapters.register_identity(
|
||||
id_dx11.unwrap(),
|
||||
adapter,
|
||||
&mut token,
|
||||
);
|
||||
return Some(id);
|
||||
}
|
||||
selected -= adapters_dx11.len();
|
||||
|
||||
backends_map! {
|
||||
let map = |(info_adapter, id_backend, mut adapters_backend, backend_hub)| {
|
||||
if selected < adapters_backend.len() {
|
||||
let adapter = Adapter::new(adapters_backend.swap_remove(selected), unsafe_extensions);
|
||||
log::info!("Adapter {} {:?}", info_adapter, adapter.raw.info);
|
||||
let id = backend_hub(self).adapters.register_identity(
|
||||
id_backend.take().unwrap(),
|
||||
adapter,
|
||||
&mut token,
|
||||
);
|
||||
return Some(id);
|
||||
}
|
||||
selected -= adapters_backend.len();
|
||||
};
|
||||
|
||||
#[vulkan]
|
||||
map(("Vulkan", &mut id_vulkan, adapters_vk, backend::Vulkan::hub)),
|
||||
#[metal]
|
||||
map(("Metal", &mut id_metal, adapters_mtl, backend::Metal::hub)),
|
||||
#[dx12]
|
||||
map(("Dx12", &mut id_dx12, adapters_dx12, backend::Dx12::hub)),
|
||||
#[dx11]
|
||||
map(("Dx11", &mut id_dx11, adapters_dx11, backend::Dx11::hub)),
|
||||
}
|
||||
|
||||
let _ = (selected, id_vulkan, id_metal, id_dx12, id_dx11);
|
||||
let _ = (
|
||||
selected,
|
||||
id_vulkan.take(),
|
||||
id_metal.take(),
|
||||
id_dx12.take(),
|
||||
id_dx11.take(),
|
||||
);
|
||||
log::warn!("Some adapters are present, but enumerating them failed!");
|
||||
None
|
||||
}
|
||||
|
@ -9,19 +9,23 @@
|
||||
unused_qualifications
|
||||
)]
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
pub mod backend {
|
||||
#[cfg(windows)]
|
||||
pub use gfx_backend_dx11::Backend as Dx11;
|
||||
#[cfg(windows)]
|
||||
pub use gfx_backend_dx12::Backend as Dx12;
|
||||
pub use gfx_backend_empty::Backend as Empty;
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
pub use gfx_backend_metal::Backend as Metal;
|
||||
|
||||
#[cfg(any(
|
||||
not(any(target_os = "ios", target_os = "macos")),
|
||||
feature = "gfx-backend-vulkan"
|
||||
))]
|
||||
pub use gfx_backend_vulkan::Backend as Vulkan;
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
pub use gfx_backend_metal::Backend as Metal;
|
||||
#[cfg(windows)]
|
||||
pub use gfx_backend_dx12::Backend as Dx12;
|
||||
#[cfg(windows)]
|
||||
pub use gfx_backend_dx11::Backend as Dx11;
|
||||
}
|
||||
|
||||
pub mod binding_model;
|
||||
|
316
wgpu-core/src/macros.rs
Normal file
316
wgpu-core/src/macros.rs
Normal file
@ -0,0 +1,316 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
macro_rules! backends {
|
||||
// one let statement per backend
|
||||
(
|
||||
#[vulkan] let $vk_field:pat = $vk_expr:expr;
|
||||
#[metal] let $mtl_field:pat = $mtl_expr:expr;
|
||||
#[dx12] let $dx12_field:pat = $dx12_expr:expr;
|
||||
#[dx11] let $dx11_field:pat = $dx11_expr:expr;
|
||||
) => {
|
||||
#[cfg(any(
|
||||
windows,
|
||||
all(unix, not(any(target_os = "ios", target_os = "macos"))),
|
||||
feature = "gfx-backend-vulkan",
|
||||
))]
|
||||
let $vk_field = $vk_expr;
|
||||
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
let $mtl_field = $mtl_expr;
|
||||
|
||||
#[cfg(windows)]
|
||||
let $dx12_field = $dx12_expr;
|
||||
|
||||
#[cfg(windows)]
|
||||
let $dx11_field = $dx11_expr;
|
||||
};
|
||||
|
||||
// one block statement per backend
|
||||
(
|
||||
#[vulkan] $vk_block:block
|
||||
#[metal] $mtl_block:block
|
||||
#[dx12] $dx12_block:block
|
||||
#[dx11] $dx11_block:block
|
||||
) => {
|
||||
#[cfg(any(
|
||||
windows,
|
||||
all(unix, not(any(target_os = "ios", target_os = "macos"))),
|
||||
feature = "gfx-backend-vulkan",
|
||||
))]
|
||||
$vk_block
|
||||
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
$mtl_block
|
||||
|
||||
#[cfg(windows)]
|
||||
$dx12_block
|
||||
|
||||
#[cfg(windows)]
|
||||
$dx11_block
|
||||
};
|
||||
|
||||
// a struct constructor with one field per backend
|
||||
(
|
||||
$Struct:path {
|
||||
#[vulkan] $vk_field:ident: $vk_expr:expr,
|
||||
#[metal] $mtl_field:ident: $mtl_expr:expr,
|
||||
#[dx12] $dx12_field:ident: $dx12_expr:expr,
|
||||
#[dx11] $dx11_field:ident: $dx11_expr:expr,
|
||||
}
|
||||
) => {{
|
||||
$Struct {
|
||||
#[cfg(any(
|
||||
windows,
|
||||
all(unix, not(any(target_os = "ios", target_os = "macos"))),
|
||||
feature = "gfx-backend-vulkan",
|
||||
))]
|
||||
$vk_field: $vk_expr,
|
||||
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
$mtl_field: $mtl_expr,
|
||||
|
||||
#[cfg(windows)]
|
||||
$dx12_field: $dx12_expr,
|
||||
|
||||
#[cfg(windows)]
|
||||
$dx11_field: $dx11_expr,
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! backends_map {
|
||||
// one let statement per backend with mapped data
|
||||
(
|
||||
let map = |$backend:pat| $map:block;
|
||||
$(
|
||||
#[$backend_attr:ident] let $pat:pat = map($expr:expr);
|
||||
)*
|
||||
) => {
|
||||
backends! {
|
||||
$(
|
||||
#[$backend_attr]
|
||||
let $pat = {
|
||||
let $backend = $expr;
|
||||
$map
|
||||
};
|
||||
)*
|
||||
}
|
||||
};
|
||||
|
||||
// one block statement per backend with mapped data
|
||||
(
|
||||
let map = |$backend:pat| $map:block;
|
||||
$(
|
||||
#[$backend_attr:ident] map($expr:expr),
|
||||
)*
|
||||
) => {
|
||||
backends! {
|
||||
$(
|
||||
#[$backend_attr]
|
||||
{
|
||||
let $backend = $expr;
|
||||
$map
|
||||
}
|
||||
)*
|
||||
}
|
||||
};
|
||||
|
||||
// a struct constructor with one field per backend with mapped data
|
||||
(
|
||||
let map = |$backend:pat| $map:block;
|
||||
$Struct:path {
|
||||
$(
|
||||
#[$backend_attr:ident] $ident:ident : map($expr:expr),
|
||||
)*
|
||||
}
|
||||
) => {
|
||||
backends! {
|
||||
$Struct {
|
||||
$(
|
||||
#[$backend_attr]
|
||||
$ident: {
|
||||
let $backend = $expr;
|
||||
$map
|
||||
},
|
||||
)*
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_backend_macro() {
|
||||
struct Foo {
|
||||
#[cfg(any(
|
||||
windows,
|
||||
all(unix, not(any(target_os = "ios", target_os = "macos"))),
|
||||
feature = "gfx-backend-vulkan",
|
||||
))]
|
||||
vulkan: u32,
|
||||
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
metal: u32,
|
||||
|
||||
#[cfg(windows)]
|
||||
dx12: u32,
|
||||
|
||||
#[cfg(windows)]
|
||||
dx11: u32,
|
||||
}
|
||||
|
||||
// test struct construction
|
||||
let test_foo: Foo = backends_map! {
|
||||
let map = |init| { init - 100 };
|
||||
Foo {
|
||||
#[vulkan] vulkan: map(101),
|
||||
#[metal] metal: map(102),
|
||||
#[dx12] dx12: map(103),
|
||||
#[dx11] dx11: map(104),
|
||||
}
|
||||
};
|
||||
|
||||
let mut vec = Vec::new();
|
||||
|
||||
// test basic statement-per-backend
|
||||
backends_map! {
|
||||
let map = |(id, chr)| {
|
||||
vec.push((id, chr));
|
||||
};
|
||||
|
||||
#[vulkan]
|
||||
map((test_foo.vulkan, 'a')),
|
||||
|
||||
#[metal]
|
||||
map((test_foo.metal, 'b')),
|
||||
|
||||
#[dx12]
|
||||
map((test_foo.dx12, 'c')),
|
||||
|
||||
#[dx11]
|
||||
map((test_foo.dx11, 'd')),
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
windows,
|
||||
all(unix, not(any(target_os = "ios", target_os = "macos"))),
|
||||
feature = "gfx-backend-vulkan",
|
||||
))]
|
||||
assert!(vec.contains(&(1, 'a')));
|
||||
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
assert!(vec.contains(&(2, 'b')));
|
||||
|
||||
#[cfg(windows)]
|
||||
assert!(vec.contains(&(3, 'c')));
|
||||
|
||||
#[cfg(windows)]
|
||||
assert!(vec.contains(&(4, 'd')));
|
||||
|
||||
// test complex statement-per-backend
|
||||
backends_map! {
|
||||
let map = |(id, pred, code)| {
|
||||
if pred(id) {
|
||||
code();
|
||||
}
|
||||
};
|
||||
|
||||
#[vulkan]
|
||||
map((test_foo.vulkan, |v| v == 1, || println!("vulkan"))),
|
||||
|
||||
#[metal]
|
||||
map((test_foo.metal, |v| v == 2, || println!("metal"))),
|
||||
|
||||
#[dx12]
|
||||
map((test_foo.dx12, |v| v == 3, || println!("dx12"))),
|
||||
|
||||
#[dx11]
|
||||
map((test_foo.dx11, |v| v == 4, || println!("dx11"))),
|
||||
}
|
||||
|
||||
// test struct construction 2
|
||||
let test_foo_2: Foo = backends! {
|
||||
Foo {
|
||||
#[vulkan]
|
||||
vulkan: 1,
|
||||
|
||||
#[metal]
|
||||
metal: 2,
|
||||
|
||||
#[dx12]
|
||||
dx12: 3,
|
||||
|
||||
#[dx11]
|
||||
dx11: 4,
|
||||
}
|
||||
};
|
||||
|
||||
backends! {
|
||||
#[vulkan]
|
||||
let var_vulkan = test_foo_2.vulkan;
|
||||
|
||||
#[metal]
|
||||
let var_metal = test_foo_2.metal;
|
||||
|
||||
#[dx12]
|
||||
let var_dx12 = test_foo_2.dx12;
|
||||
|
||||
#[dx11]
|
||||
let var_dx11 = test_foo_2.dx11;
|
||||
}
|
||||
|
||||
backends_map! {
|
||||
let map = |(id, chr, var)| { (chr, id, var) };
|
||||
|
||||
#[vulkan]
|
||||
let var_vulkan = map((test_foo_2.vulkan, 'a', var_vulkan));
|
||||
|
||||
#[metal]
|
||||
let var_metal = map((test_foo_2.metal, 'b', var_metal));
|
||||
|
||||
#[dx12]
|
||||
let var_dx12 = map((test_foo_2.dx12, 'c', var_dx12));
|
||||
|
||||
#[dx11]
|
||||
let var_dx11 = map((test_foo_2.dx11, 'd', var_dx11));
|
||||
}
|
||||
|
||||
backends! {
|
||||
#[vulkan]
|
||||
{
|
||||
println!("backend int: {:?}", var_vulkan);
|
||||
}
|
||||
|
||||
#[metal]
|
||||
{
|
||||
println!("backend int: {:?}", var_metal);
|
||||
}
|
||||
|
||||
#[dx12]
|
||||
{
|
||||
println!("backend int: {:?}", var_dx12);
|
||||
}
|
||||
|
||||
#[dx11]
|
||||
{
|
||||
println!("backend int: {:?}", var_dx11);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
windows,
|
||||
all(unix, not(any(target_os = "ios", target_os = "macos"))),
|
||||
feature = "gfx-backend-vulkan",
|
||||
))]
|
||||
let _ = var_vulkan;
|
||||
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
let _ = var_metal;
|
||||
|
||||
#[cfg(windows)]
|
||||
let _ = var_dx12;
|
||||
|
||||
#[cfg(windows)]
|
||||
let _ = var_dx11;
|
||||
}
|
Loading…
Reference in New Issue
Block a user