mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 00:03:29 +00:00
Core's Surface, Instance and Adapter use now dynamic hal types
This commit is contained in:
parent
7c7e4164f1
commit
04cadfb369
@ -56,7 +56,7 @@ impl Global {
|
||||
) -> Result<wgt::SurfaceCapabilities, instance::GetSurfaceSupportError> {
|
||||
profiling::scope!("Surface::get_capabilities");
|
||||
self.fetch_adapter_and_surface::<A, _, _>(surface_id, adapter_id, |adapter, surface| {
|
||||
let mut hal_caps = surface.get_capabilities(adapter)?;
|
||||
let mut hal_caps = surface.get_capabilities::<A>(A::VARIANT, adapter)?;
|
||||
|
||||
hal_caps.formats.sort_by_key(|f| !f.is_srgb());
|
||||
|
||||
@ -1765,7 +1765,6 @@ impl Global {
|
||||
device_id: DeviceId,
|
||||
config: &wgt::SurfaceConfiguration<Vec<TextureFormat>>,
|
||||
) -> Option<present::ConfigureSurfaceError> {
|
||||
use hal::Surface as _;
|
||||
use present::ConfigureSurfaceError as E;
|
||||
profiling::scope!("surface_configure");
|
||||
|
||||
@ -1909,7 +1908,7 @@ impl Global {
|
||||
Err(_) => break 'error E::InvalidSurface,
|
||||
};
|
||||
|
||||
let caps = match surface.get_capabilities(&device.adapter) {
|
||||
let caps = match surface.get_capabilities::<A>(A::VARIANT, &device.adapter) {
|
||||
Ok(caps) => caps,
|
||||
Err(_) => break 'error E::UnsupportedQueueFamily,
|
||||
};
|
||||
@ -1990,11 +1989,8 @@ impl Global {
|
||||
//
|
||||
// https://github.com/gfx-rs/wgpu/issues/4105
|
||||
|
||||
match unsafe {
|
||||
A::surface_as_hal(surface)
|
||||
.unwrap()
|
||||
.configure(device.raw().as_any().downcast_ref().unwrap(), &hal_config)
|
||||
} {
|
||||
let surface_raw = surface.raw(A::VARIANT).unwrap();
|
||||
match unsafe { surface_raw.configure(device.raw(), &hal_config) } {
|
||||
Ok(()) => (),
|
||||
Err(error) => {
|
||||
break 'error match error {
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use wgt::Backend;
|
||||
|
||||
use crate::{
|
||||
@ -11,14 +13,7 @@ use crate::{
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct GlobalReport {
|
||||
pub surfaces: RegistryReport,
|
||||
#[cfg(vulkan)]
|
||||
pub vulkan: Option<HubReport>,
|
||||
#[cfg(metal)]
|
||||
pub metal: Option<HubReport>,
|
||||
#[cfg(dx12)]
|
||||
pub dx12: Option<HubReport>,
|
||||
#[cfg(gles)]
|
||||
pub gl: Option<HubReport>,
|
||||
pub report_per_backend: HashMap<Backend, HubReport>,
|
||||
}
|
||||
|
||||
impl GlobalReport {
|
||||
@ -26,17 +21,7 @@ impl GlobalReport {
|
||||
&self.surfaces
|
||||
}
|
||||
pub fn hub_report(&self, backend: Backend) -> &HubReport {
|
||||
match backend {
|
||||
#[cfg(vulkan)]
|
||||
Backend::Vulkan => self.vulkan.as_ref().unwrap(),
|
||||
#[cfg(metal)]
|
||||
Backend::Metal => self.metal.as_ref().unwrap(),
|
||||
#[cfg(dx12)]
|
||||
Backend::Dx12 => self.dx12.as_ref().unwrap(),
|
||||
#[cfg(gles)]
|
||||
Backend::Gl => self.gl.as_ref().unwrap(),
|
||||
_ => panic!("HubReport is not supported on this backend"),
|
||||
}
|
||||
self.report_per_backend.get(&backend).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,8 +46,14 @@ impl Global {
|
||||
/// Refer to the creation of wgpu-hal Instance for every backend.
|
||||
pub unsafe fn from_hal_instance<A: HalApi>(name: &str, hal_instance: A::Instance) -> Self {
|
||||
profiling::scope!("Global::new");
|
||||
|
||||
let dyn_instance: Box<dyn hal::DynInstance> = Box::new(hal_instance);
|
||||
Self {
|
||||
instance: A::create_instance_from_hal(name, hal_instance),
|
||||
instance: Instance {
|
||||
name: name.to_owned(),
|
||||
instance_per_backend: std::iter::once((A::VARIANT, dyn_instance)).collect(),
|
||||
..Default::default()
|
||||
},
|
||||
surfaces: Registry::without_backend(),
|
||||
hubs: Hubs::new(),
|
||||
}
|
||||
@ -72,7 +63,13 @@ impl Global {
|
||||
///
|
||||
/// - The raw instance handle returned must not be manually destroyed.
|
||||
pub unsafe fn instance_as_hal<A: HalApi>(&self) -> Option<&A::Instance> {
|
||||
A::instance_as_hal(&self.instance)
|
||||
self.instance.raw(A::VARIANT).map(|instance| {
|
||||
instance
|
||||
.as_any()
|
||||
.downcast_ref()
|
||||
// This should be impossible. It would mean that backend instance and enum type are mismatching.
|
||||
.expect("Stored instance is not of the correct type")
|
||||
})
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
@ -88,32 +85,41 @@ impl Global {
|
||||
}
|
||||
|
||||
pub fn generate_report(&self) -> GlobalReport {
|
||||
let mut report_per_backend = HashMap::default();
|
||||
let instance_per_backend = &self.instance.instance_per_backend;
|
||||
|
||||
#[cfg(vulkan)]
|
||||
if instance_per_backend
|
||||
.iter()
|
||||
.any(|(backend, _)| backend == &Backend::Vulkan)
|
||||
{
|
||||
report_per_backend.insert(Backend::Vulkan, self.hubs.vulkan.generate_report());
|
||||
};
|
||||
#[cfg(metal)]
|
||||
if instance_per_backend
|
||||
.iter()
|
||||
.any(|(backend, _)| backend == &Backend::Metal)
|
||||
{
|
||||
report_per_backend.insert(Backend::Metal, self.hubs.metal.generate_report());
|
||||
};
|
||||
#[cfg(dx12)]
|
||||
if instance_per_backend
|
||||
.iter()
|
||||
.any(|(backend, _)| backend == &Backend::Dx12)
|
||||
{
|
||||
report_per_backend.insert(Backend::Dx12, self.hubs.dx12.generate_report());
|
||||
};
|
||||
#[cfg(gles)]
|
||||
if instance_per_backend
|
||||
.iter()
|
||||
.any(|(backend, _)| backend == &Backend::Gl)
|
||||
{
|
||||
report_per_backend.insert(Backend::Gl, self.hubs.gl.generate_report());
|
||||
};
|
||||
|
||||
GlobalReport {
|
||||
surfaces: self.surfaces.generate_report(),
|
||||
#[cfg(vulkan)]
|
||||
vulkan: if self.instance.vulkan.is_some() {
|
||||
Some(self.hubs.vulkan.generate_report())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
#[cfg(metal)]
|
||||
metal: if self.instance.metal.is_some() {
|
||||
Some(self.hubs.metal.generate_report())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
#[cfg(dx12)]
|
||||
dx12: if self.instance.dx12.is_some() {
|
||||
Some(self.hubs.dx12.generate_report())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
#[cfg(gles)]
|
||||
gl: if self.instance.gl.is_some() {
|
||||
Some(self.hubs.gl.generate_report())
|
||||
} else {
|
||||
None
|
||||
},
|
||||
report_per_backend,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,116 +1,53 @@
|
||||
use wgt::{Backend, WasmNotSendSync};
|
||||
|
||||
use crate::{
|
||||
global::Global,
|
||||
hub::Hub,
|
||||
instance::{Instance, Surface},
|
||||
};
|
||||
use crate::{global::Global, hub::Hub};
|
||||
|
||||
pub trait HalApi: hal::Api + 'static + WasmNotSendSync {
|
||||
const VARIANT: Backend;
|
||||
fn create_instance_from_hal(name: &str, hal_instance: Self::Instance) -> Instance;
|
||||
fn instance_as_hal(instance: &Instance) -> Option<&Self::Instance>;
|
||||
|
||||
fn hub(global: &Global) -> &Hub<Self>;
|
||||
fn surface_as_hal(surface: &Surface) -> Option<&Self::Surface>;
|
||||
}
|
||||
|
||||
impl HalApi for hal::api::Empty {
|
||||
const VARIANT: Backend = Backend::Empty;
|
||||
fn create_instance_from_hal(_: &str, _: Self::Instance) -> Instance {
|
||||
unimplemented!("called empty api")
|
||||
}
|
||||
fn instance_as_hal(_: &Instance) -> Option<&Self::Instance> {
|
||||
unimplemented!("called empty api")
|
||||
}
|
||||
|
||||
fn hub(_: &Global) -> &Hub<Self> {
|
||||
unimplemented!("called empty api")
|
||||
}
|
||||
fn surface_as_hal(_: &Surface) -> Option<&Self::Surface> {
|
||||
unimplemented!("called empty api")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(vulkan)]
|
||||
impl HalApi for hal::api::Vulkan {
|
||||
const VARIANT: Backend = Backend::Vulkan;
|
||||
fn create_instance_from_hal(name: &str, hal_instance: Self::Instance) -> Instance {
|
||||
Instance {
|
||||
name: name.to_owned(),
|
||||
vulkan: Some(hal_instance),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
fn instance_as_hal(instance: &Instance) -> Option<&Self::Instance> {
|
||||
instance.vulkan.as_ref()
|
||||
}
|
||||
|
||||
fn hub(global: &Global) -> &Hub<Self> {
|
||||
&global.hubs.vulkan
|
||||
}
|
||||
fn surface_as_hal(surface: &Surface) -> Option<&Self::Surface> {
|
||||
surface.vulkan.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(metal)]
|
||||
impl HalApi for hal::api::Metal {
|
||||
const VARIANT: Backend = Backend::Metal;
|
||||
fn create_instance_from_hal(name: &str, hal_instance: Self::Instance) -> Instance {
|
||||
Instance {
|
||||
name: name.to_owned(),
|
||||
metal: Some(hal_instance),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
fn instance_as_hal(instance: &Instance) -> Option<&Self::Instance> {
|
||||
instance.metal.as_ref()
|
||||
}
|
||||
|
||||
fn hub(global: &Global) -> &Hub<Self> {
|
||||
&global.hubs.metal
|
||||
}
|
||||
fn surface_as_hal(surface: &Surface) -> Option<&Self::Surface> {
|
||||
surface.metal.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(dx12)]
|
||||
impl HalApi for hal::api::Dx12 {
|
||||
const VARIANT: Backend = Backend::Dx12;
|
||||
fn create_instance_from_hal(name: &str, hal_instance: Self::Instance) -> Instance {
|
||||
Instance {
|
||||
name: name.to_owned(),
|
||||
dx12: Some(hal_instance),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
fn instance_as_hal(instance: &Instance) -> Option<&Self::Instance> {
|
||||
instance.dx12.as_ref()
|
||||
}
|
||||
|
||||
fn hub(global: &Global) -> &Hub<Self> {
|
||||
&global.hubs.dx12
|
||||
}
|
||||
fn surface_as_hal(surface: &Surface) -> Option<&Self::Surface> {
|
||||
surface.dx12.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(gles)]
|
||||
impl HalApi for hal::api::Gles {
|
||||
const VARIANT: Backend = Backend::Gl;
|
||||
fn create_instance_from_hal(name: &str, hal_instance: Self::Instance) -> Instance {
|
||||
#[allow(clippy::needless_update)]
|
||||
Instance {
|
||||
name: name.to_owned(),
|
||||
gl: Some(hal_instance),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
fn instance_as_hal(instance: &Instance) -> Option<&Self::Instance> {
|
||||
instance.gl.as_ref()
|
||||
}
|
||||
|
||||
fn hub(global: &Global) -> &Hub<Self> {
|
||||
&global.hubs.gl
|
||||
}
|
||||
fn surface_as_hal(surface: &Surface) -> Option<&Self::Surface> {
|
||||
surface.gl.as_ref()
|
||||
}
|
||||
}
|
||||
|
@ -215,8 +215,6 @@ impl<A: HalApi> Hub<A> {
|
||||
}
|
||||
|
||||
pub(crate) fn clear(&self, surface_guard: &Storage<Surface>) {
|
||||
use hal::Surface;
|
||||
|
||||
let mut devices = self.devices.write();
|
||||
for element in devices.map.iter() {
|
||||
if let Element::Occupied(ref device, _) = *element {
|
||||
@ -242,10 +240,9 @@ impl<A: HalApi> Hub<A> {
|
||||
if let Element::Occupied(ref surface, _epoch) = *element {
|
||||
if let Some(ref mut present) = surface.presentation.lock().take() {
|
||||
if let Some(device) = present.device.downcast_ref::<A>() {
|
||||
let suf = A::surface_as_hal(surface);
|
||||
let suf = surface.raw(A::VARIANT);
|
||||
unsafe {
|
||||
suf.unwrap()
|
||||
.unconfigure(device.raw().as_any().downcast_ref().unwrap());
|
||||
suf.unwrap().unconfigure(device.raw());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,12 +15,9 @@ use crate::{
|
||||
|
||||
use wgt::{Backend, Backends, PowerPreference};
|
||||
|
||||
use hal::{Adapter as _, Instance as _, OpenDevice};
|
||||
use thiserror::Error;
|
||||
|
||||
pub type RequestAdapterOptions = wgt::RequestAdapterOptions<SurfaceId>;
|
||||
type HalInstance<A> = <A as hal::Api>::Instance;
|
||||
type HalSurface<A> = <A as hal::Api>::Surface;
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
@ -58,20 +55,20 @@ fn downlevel_default_limits_less_than_default_limits() {
|
||||
pub struct Instance {
|
||||
#[allow(dead_code)]
|
||||
pub name: String,
|
||||
#[cfg(vulkan)]
|
||||
pub vulkan: Option<HalInstance<hal::api::Vulkan>>,
|
||||
#[cfg(metal)]
|
||||
pub metal: Option<HalInstance<hal::api::Metal>>,
|
||||
#[cfg(dx12)]
|
||||
pub dx12: Option<HalInstance<hal::api::Dx12>>,
|
||||
#[cfg(gles)]
|
||||
pub gl: Option<HalInstance<hal::api::Gles>>,
|
||||
/// List of instances per backend.
|
||||
///
|
||||
/// The ordering in this list implies prioritization and needs to be preserved.
|
||||
pub instance_per_backend: Vec<(Backend, Box<dyn hal::DynInstance>)>,
|
||||
pub flags: wgt::InstanceFlags,
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
pub fn new(name: &str, instance_desc: wgt::InstanceDescriptor) -> Self {
|
||||
fn init<A: HalApi>(_: A, instance_desc: &wgt::InstanceDescriptor) -> Option<A::Instance> {
|
||||
fn init<A: HalApi>(
|
||||
_: A,
|
||||
instance_desc: &wgt::InstanceDescriptor,
|
||||
instance_per_backend: &mut Vec<(Backend, Box<dyn hal::DynInstance>)>,
|
||||
) {
|
||||
if instance_desc.backends.contains(A::VARIANT.into()) {
|
||||
let hal_desc = hal::InstanceDescriptor {
|
||||
name: "wgpu",
|
||||
@ -79,10 +76,12 @@ impl Instance {
|
||||
dx12_shader_compiler: instance_desc.dx12_shader_compiler.clone(),
|
||||
gles_minor_version: instance_desc.gles_minor_version,
|
||||
};
|
||||
match unsafe { hal::Instance::init(&hal_desc) } {
|
||||
|
||||
use hal::Instance as _;
|
||||
match unsafe { A::Instance::init(&hal_desc) } {
|
||||
Ok(instance) => {
|
||||
log::debug!("Instance::new: created {:?} backend", A::VARIANT);
|
||||
Some(instance)
|
||||
instance_per_backend.push((A::VARIANT, Box::new(instance)));
|
||||
}
|
||||
Err(err) => {
|
||||
log::debug!(
|
||||
@ -90,41 +89,43 @@ impl Instance {
|
||||
A::VARIANT,
|
||||
err
|
||||
);
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log::trace!("Instance::new: backend {:?} not requested", A::VARIANT);
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
let mut instance_per_backend = Vec::new();
|
||||
|
||||
#[cfg(vulkan)]
|
||||
init(hal::api::Vulkan, &instance_desc, &mut instance_per_backend);
|
||||
#[cfg(metal)]
|
||||
init(hal::api::Metal, &instance_desc, &mut instance_per_backend);
|
||||
#[cfg(dx12)]
|
||||
init(hal::api::Dx12, &instance_desc, &mut instance_per_backend);
|
||||
#[cfg(gles)]
|
||||
init(hal::api::Gles, &instance_desc, &mut instance_per_backend);
|
||||
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
#[cfg(vulkan)]
|
||||
vulkan: init(hal::api::Vulkan, &instance_desc),
|
||||
#[cfg(metal)]
|
||||
metal: init(hal::api::Metal, &instance_desc),
|
||||
#[cfg(dx12)]
|
||||
dx12: init(hal::api::Dx12, &instance_desc),
|
||||
#[cfg(gles)]
|
||||
gl: init(hal::api::Gles, &instance_desc),
|
||||
instance_per_backend,
|
||||
flags: instance_desc.flags,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn raw(&self, backend: Backend) -> Option<&dyn hal::DynInstance> {
|
||||
self.instance_per_backend
|
||||
.iter()
|
||||
.find_map(|(instance_backend, instance)| {
|
||||
(*instance_backend == backend).then(|| instance.as_ref())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Surface {
|
||||
pub(crate) presentation: Mutex<Option<Presentation>>,
|
||||
|
||||
#[cfg(vulkan)]
|
||||
pub vulkan: Option<HalSurface<hal::api::Vulkan>>,
|
||||
#[cfg(metal)]
|
||||
pub metal: Option<HalSurface<hal::api::Metal>>,
|
||||
#[cfg(dx12)]
|
||||
pub dx12: Option<HalSurface<hal::api::Dx12>>,
|
||||
#[cfg(gles)]
|
||||
pub gl: Option<HalSurface<hal::api::Gles>>,
|
||||
pub surface_per_backend: HashMap<Backend, Box<dyn hal::DynSurface>>,
|
||||
}
|
||||
|
||||
impl ResourceType for Surface {
|
||||
@ -137,34 +138,41 @@ impl crate::storage::StorageItem for Surface {
|
||||
impl Surface {
|
||||
pub fn get_capabilities<A: HalApi>(
|
||||
&self,
|
||||
backend: Backend,
|
||||
adapter: &Adapter<A>,
|
||||
) -> Result<hal::SurfaceCapabilities, GetSurfaceSupportError> {
|
||||
self.get_capabilities_with_raw(&adapter.raw)
|
||||
self.get_capabilities_with_raw(backend, &adapter.raw)
|
||||
}
|
||||
|
||||
pub fn get_capabilities_with_raw<A: HalApi>(
|
||||
pub fn get_capabilities_with_raw(
|
||||
&self,
|
||||
adapter: &hal::ExposedAdapter<A>,
|
||||
backend: Backend,
|
||||
adapter: &hal::DynExposedAdapter,
|
||||
) -> Result<hal::SurfaceCapabilities, GetSurfaceSupportError> {
|
||||
let suf = A::surface_as_hal(self).ok_or(GetSurfaceSupportError::Unsupported)?;
|
||||
let suf = self
|
||||
.raw(backend)
|
||||
.ok_or(GetSurfaceSupportError::Unsupported)?;
|
||||
profiling::scope!("surface_capabilities");
|
||||
let caps = unsafe {
|
||||
adapter
|
||||
.adapter
|
||||
.surface_capabilities(suf)
|
||||
.ok_or(GetSurfaceSupportError::Unsupported)?
|
||||
};
|
||||
let caps = unsafe { adapter.adapter.surface_capabilities(suf) }
|
||||
.ok_or(GetSurfaceSupportError::Unsupported)?;
|
||||
|
||||
Ok(caps)
|
||||
}
|
||||
|
||||
pub fn raw(&self, backend: Backend) -> Option<&dyn hal::DynSurface> {
|
||||
self.surface_per_backend
|
||||
.get(&backend)
|
||||
.map(|surface| surface.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Adapter<A: HalApi> {
|
||||
pub(crate) raw: hal::ExposedAdapter<A>,
|
||||
pub(crate) raw: hal::DynExposedAdapter,
|
||||
_marker: std::marker::PhantomData<A>,
|
||||
}
|
||||
|
||||
impl<A: HalApi> Adapter<A> {
|
||||
fn new(mut raw: hal::ExposedAdapter<A>) -> Self {
|
||||
fn new(mut raw: hal::DynExposedAdapter) -> Self {
|
||||
// WebGPU requires this offset alignment as lower bound on all adapters.
|
||||
const MIN_BUFFER_OFFSET_ALIGNMENT_LOWER_BOUND: u32 = 32;
|
||||
|
||||
@ -177,7 +185,10 @@ impl<A: HalApi> Adapter<A> {
|
||||
.min_storage_buffer_offset_alignment
|
||||
.max(MIN_BUFFER_OFFSET_ALIGNMENT_LOWER_BOUND);
|
||||
|
||||
Self { raw }
|
||||
Self {
|
||||
raw,
|
||||
_marker: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_surface_supported(&self, surface: &Surface) -> bool {
|
||||
@ -185,7 +196,7 @@ impl<A: HalApi> Adapter<A> {
|
||||
//
|
||||
// This could occur if the user is running their app on Wayland but Vulkan does not support
|
||||
// VK_KHR_wayland_surface.
|
||||
surface.get_capabilities(self).is_ok()
|
||||
surface.get_capabilities(A::VARIANT, self).is_ok()
|
||||
}
|
||||
|
||||
pub(crate) fn get_texture_format_features(
|
||||
@ -259,7 +270,7 @@ impl<A: HalApi> Adapter<A> {
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn create_device_and_queue_from_hal(
|
||||
self: &Arc<Self>,
|
||||
hal_device: OpenDevice<A>,
|
||||
hal_device: hal::DynOpenDevice,
|
||||
desc: &DeviceDescriptor,
|
||||
instance_flags: wgt::InstanceFlags,
|
||||
trace_path: Option<&std::path::Path>,
|
||||
@ -267,15 +278,15 @@ impl<A: HalApi> Adapter<A> {
|
||||
api_log!("Adapter::create_device");
|
||||
|
||||
if let Ok(device) = Device::new(
|
||||
Box::new(hal_device.device),
|
||||
&hal_device.queue,
|
||||
hal_device.device,
|
||||
hal_device.queue.as_ref(),
|
||||
self,
|
||||
desc,
|
||||
trace_path,
|
||||
instance_flags,
|
||||
) {
|
||||
let device = Arc::new(device);
|
||||
let queue = Arc::new(Queue::new(device.clone(), Box::new(hal_device.queue)));
|
||||
let queue = Arc::new(Queue::new(device.clone(), hal_device.queue));
|
||||
device.set_queue(&queue);
|
||||
return Ok((device, queue));
|
||||
}
|
||||
@ -456,85 +467,42 @@ impl Global {
|
||||
) -> Result<SurfaceId, CreateSurfaceError> {
|
||||
profiling::scope!("Instance::create_surface");
|
||||
|
||||
fn init<A: HalApi>(
|
||||
errors: &mut HashMap<Backend, hal::InstanceError>,
|
||||
any_created: &mut bool,
|
||||
backend: Backend,
|
||||
inst: &Option<A::Instance>,
|
||||
display_handle: raw_window_handle::RawDisplayHandle,
|
||||
window_handle: raw_window_handle::RawWindowHandle,
|
||||
) -> Option<HalSurface<A>> {
|
||||
inst.as_ref().and_then(|inst| {
|
||||
match unsafe { inst.create_surface(display_handle, window_handle) } {
|
||||
Ok(raw) => {
|
||||
*any_created = true;
|
||||
Some(raw)
|
||||
}
|
||||
Err(err) => {
|
||||
log::debug!(
|
||||
"Instance::create_surface: failed to create surface for {:?}: {:?}",
|
||||
backend,
|
||||
err
|
||||
);
|
||||
errors.insert(backend, err);
|
||||
None
|
||||
}
|
||||
let mut errors = HashMap::default();
|
||||
let mut surface_per_backend = HashMap::default();
|
||||
|
||||
for (backend, instance) in &self.instance.instance_per_backend {
|
||||
match unsafe {
|
||||
instance
|
||||
.as_ref()
|
||||
.create_surface(display_handle, window_handle)
|
||||
} {
|
||||
Ok(raw) => {
|
||||
surface_per_backend.insert(*backend, raw);
|
||||
}
|
||||
})
|
||||
Err(err) => {
|
||||
log::debug!(
|
||||
"Instance::create_surface: failed to create surface for {:?}: {:?}",
|
||||
backend,
|
||||
err
|
||||
);
|
||||
errors.insert(*backend, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut errors = HashMap::default();
|
||||
let mut any_created = false;
|
||||
|
||||
let surface = Surface {
|
||||
presentation: Mutex::new(rank::SURFACE_PRESENTATION, None),
|
||||
|
||||
#[cfg(vulkan)]
|
||||
vulkan: init::<hal::api::Vulkan>(
|
||||
&mut errors,
|
||||
&mut any_created,
|
||||
Backend::Vulkan,
|
||||
&self.instance.vulkan,
|
||||
display_handle,
|
||||
window_handle,
|
||||
),
|
||||
#[cfg(metal)]
|
||||
metal: init::<hal::api::Metal>(
|
||||
&mut errors,
|
||||
&mut any_created,
|
||||
Backend::Metal,
|
||||
&self.instance.metal,
|
||||
display_handle,
|
||||
window_handle,
|
||||
),
|
||||
#[cfg(dx12)]
|
||||
dx12: init::<hal::api::Dx12>(
|
||||
&mut errors,
|
||||
&mut any_created,
|
||||
Backend::Dx12,
|
||||
&self.instance.dx12,
|
||||
display_handle,
|
||||
window_handle,
|
||||
),
|
||||
#[cfg(gles)]
|
||||
gl: init::<hal::api::Gles>(
|
||||
&mut errors,
|
||||
&mut any_created,
|
||||
Backend::Gl,
|
||||
&self.instance.gl,
|
||||
display_handle,
|
||||
window_handle,
|
||||
),
|
||||
};
|
||||
|
||||
if any_created {
|
||||
#[allow(clippy::arc_with_non_send_sync)]
|
||||
let id = self.surfaces.prepare(id_in).assign(Arc::new(surface));
|
||||
Ok(id)
|
||||
} else {
|
||||
if surface_per_backend.is_empty() {
|
||||
Err(CreateSurfaceError::FailedToCreateSurfaceForAnyBackend(
|
||||
errors,
|
||||
))
|
||||
} else {
|
||||
let surface = Surface {
|
||||
presentation: Mutex::new(rank::SURFACE_PRESENTATION, None),
|
||||
surface_per_backend,
|
||||
};
|
||||
|
||||
#[allow(clippy::arc_with_non_send_sync)]
|
||||
let id = self.surfaces.prepare(id_in).assign(Arc::new(surface));
|
||||
Ok(id)
|
||||
}
|
||||
}
|
||||
|
||||
@ -549,33 +517,31 @@ impl Global {
|
||||
) -> Result<SurfaceId, CreateSurfaceError> {
|
||||
profiling::scope!("Instance::create_surface_metal");
|
||||
|
||||
let instance = self
|
||||
.instance
|
||||
.raw(Backend::Metal)
|
||||
.ok_or(CreateSurfaceError::BackendNotEnabled(Backend::Metal))?;
|
||||
let instance_metal: &hal::metal::Instance = instance.as_any().downcast_ref().unwrap();
|
||||
|
||||
let layer = layer.cast();
|
||||
// SAFETY: We do this cast and deref. (rather than using `metal` to get the
|
||||
// object we want) to avoid direct coupling on the `metal` crate.
|
||||
//
|
||||
// To wit, this pointer…
|
||||
//
|
||||
// - …is properly aligned.
|
||||
// - …is dereferenceable to a `MetalLayerRef` as an invariant of the `metal`
|
||||
// field.
|
||||
// - …points to an _initialized_ `MetalLayerRef`.
|
||||
// - …is only ever aliased via an immutable reference that lives within this
|
||||
// lexical scope.
|
||||
let layer = unsafe { &*layer };
|
||||
let raw_surface: Box<dyn hal::DynSurface> =
|
||||
Box::new(instance_metal.create_surface_from_layer(layer));
|
||||
|
||||
let surface = Surface {
|
||||
presentation: Mutex::new(rank::SURFACE_PRESENTATION, None),
|
||||
metal: Some(self.instance.metal.as_ref().map_or(
|
||||
Err(CreateSurfaceError::BackendNotEnabled(Backend::Metal)),
|
||||
|inst| {
|
||||
let layer = layer.cast();
|
||||
// SAFETY: We do this cast and deref. (rather than using `metal` to get the
|
||||
// object we want) to avoid direct coupling on the `metal` crate.
|
||||
//
|
||||
// To wit, this pointer…
|
||||
//
|
||||
// - …is properly aligned.
|
||||
// - …is dereferenceable to a `MetalLayerRef` as an invariant of the `metal`
|
||||
// field.
|
||||
// - …points to an _initialized_ `MetalLayerRef`.
|
||||
// - …is only ever aliased via an immutable reference that lives within this
|
||||
// lexical scope.
|
||||
let layer = unsafe { &*layer };
|
||||
Ok(inst.create_surface_from_layer(layer))
|
||||
},
|
||||
)?),
|
||||
#[cfg(dx12)]
|
||||
dx12: None,
|
||||
#[cfg(vulkan)]
|
||||
vulkan: None,
|
||||
#[cfg(gles)]
|
||||
gl: None,
|
||||
surface_per_backend: std::iter::once((Backend::Metal, raw_surface)).collect(),
|
||||
};
|
||||
|
||||
let id = self.surfaces.prepare(id_in).assign(Arc::new(surface));
|
||||
@ -586,22 +552,18 @@ impl Global {
|
||||
fn instance_create_surface_dx12(
|
||||
&self,
|
||||
id_in: Option<SurfaceId>,
|
||||
create_surface_func: impl FnOnce(&HalInstance<hal::api::Dx12>) -> HalSurface<hal::api::Dx12>,
|
||||
create_surface_func: impl FnOnce(&hal::dx12::Instance) -> hal::dx12::Surface,
|
||||
) -> Result<SurfaceId, CreateSurfaceError> {
|
||||
let instance = self
|
||||
.instance
|
||||
.raw(Backend::Dx12)
|
||||
.ok_or(CreateSurfaceError::BackendNotEnabled(Backend::Dx12))?;
|
||||
let instance_dx12 = instance.as_any().downcast_ref().unwrap();
|
||||
let surface: Box<dyn hal::DynSurface> = Box::new(create_surface_func(instance_dx12));
|
||||
|
||||
let surface = Surface {
|
||||
presentation: Mutex::new(rank::SURFACE_PRESENTATION, None),
|
||||
dx12: Some(create_surface_func(
|
||||
self.instance
|
||||
.dx12
|
||||
.as_ref()
|
||||
.ok_or(CreateSurfaceError::BackendNotEnabled(Backend::Dx12))?,
|
||||
)),
|
||||
#[cfg(metal)]
|
||||
metal: None,
|
||||
#[cfg(vulkan)]
|
||||
vulkan: None,
|
||||
#[cfg(gles)]
|
||||
gl: None,
|
||||
surface_per_backend: std::iter::once((Backend::Dx12, surface)).collect(),
|
||||
};
|
||||
|
||||
let id = self.surfaces.prepare(id_in).assign(Arc::new(surface));
|
||||
@ -658,11 +620,10 @@ impl Global {
|
||||
|
||||
api_log!("Surface::drop {id:?}");
|
||||
|
||||
fn unconfigure<A: HalApi>(surface: &Option<HalSurface<A>>, present: &Presentation) {
|
||||
if let Some(surface) = surface {
|
||||
fn unconfigure<A: HalApi>(surface: &Surface, present: &Presentation) {
|
||||
if let Some(surface) = surface.raw(A::VARIANT) {
|
||||
if let Some(device) = present.device.downcast_ref::<A>() {
|
||||
use hal::Surface;
|
||||
unsafe { surface.unconfigure(device.raw().as_any().downcast_ref().unwrap()) };
|
||||
unsafe { surface.unconfigure(device.raw()) };
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -672,27 +633,31 @@ impl Global {
|
||||
.expect("Surface cannot be destroyed because is still in use");
|
||||
|
||||
if let Some(present) = surface.presentation.lock().take() {
|
||||
// TODO(#5124): Becomes a loop once we use Arc<Device>
|
||||
#[cfg(vulkan)]
|
||||
unconfigure::<hal::api::Vulkan>(&surface.vulkan, &present);
|
||||
unconfigure::<hal::api::Vulkan>(&surface, &present);
|
||||
#[cfg(metal)]
|
||||
unconfigure::<hal::api::Metal>(&surface.metal, &present);
|
||||
unconfigure::<hal::api::Metal>(&surface, &present);
|
||||
#[cfg(dx12)]
|
||||
unconfigure::<hal::api::Dx12>(&surface.dx12, &present);
|
||||
unconfigure::<hal::api::Dx12>(&surface, &present);
|
||||
#[cfg(gles)]
|
||||
unconfigure::<hal::api::Gles>(&surface.gl, &present);
|
||||
unconfigure::<hal::api::Gles>(&surface, &present);
|
||||
}
|
||||
drop(surface)
|
||||
}
|
||||
|
||||
fn enumerate<A: HalApi>(
|
||||
&self,
|
||||
_: A,
|
||||
instance: &Option<A::Instance>,
|
||||
inputs: &AdapterInputs<markers::Adapter>,
|
||||
list: &mut Vec<AdapterId>,
|
||||
) {
|
||||
let inst = match *instance {
|
||||
Some(ref inst) => inst,
|
||||
let inst = match self
|
||||
.instance
|
||||
.instance_per_backend
|
||||
.iter()
|
||||
.find(|(backend, _)| backend == &A::VARIANT)
|
||||
{
|
||||
Some((_, inst)) => inst.as_ref(),
|
||||
None => return,
|
||||
};
|
||||
let id_backend = match inputs.find(A::VARIANT) {
|
||||
@ -700,8 +665,8 @@ impl Global {
|
||||
None => return,
|
||||
};
|
||||
|
||||
profiling::scope!("enumerating", &*format!("{:?}", A::VARIANT));
|
||||
let hub = HalApi::hub(self);
|
||||
profiling::scope!("enumerating", &*format!("{:?}", backend));
|
||||
let hub: &crate::hub::Hub<A> = HalApi::hub(self);
|
||||
|
||||
let hal_adapters = unsafe { inst.enumerate_adapters(None) };
|
||||
for raw in hal_adapters {
|
||||
@ -719,23 +684,13 @@ impl Global {
|
||||
let mut adapters = Vec::new();
|
||||
|
||||
#[cfg(vulkan)]
|
||||
self.enumerate(
|
||||
hal::api::Vulkan,
|
||||
&self.instance.vulkan,
|
||||
&inputs,
|
||||
&mut adapters,
|
||||
);
|
||||
self.enumerate::<hal::vulkan::Api>(&inputs, &mut adapters);
|
||||
#[cfg(metal)]
|
||||
self.enumerate(
|
||||
hal::api::Metal,
|
||||
&self.instance.metal,
|
||||
&inputs,
|
||||
&mut adapters,
|
||||
);
|
||||
self.enumerate::<hal::metal::Api>(&inputs, &mut adapters);
|
||||
#[cfg(dx12)]
|
||||
self.enumerate(hal::api::Dx12, &self.instance.dx12, &inputs, &mut adapters);
|
||||
self.enumerate::<hal::dx12::Api>(&inputs, &mut adapters);
|
||||
#[cfg(gles)]
|
||||
self.enumerate(hal::api::Gles, &self.instance.gl, &inputs, &mut adapters);
|
||||
self.enumerate::<hal::gles::Api>(&inputs, &mut adapters);
|
||||
|
||||
adapters
|
||||
}
|
||||
@ -744,7 +699,7 @@ impl Global {
|
||||
&self,
|
||||
selected: &mut usize,
|
||||
new_id: Option<AdapterId>,
|
||||
mut list: Vec<hal::ExposedAdapter<A>>,
|
||||
mut list: Vec<hal::DynExposedAdapter>,
|
||||
) -> Option<AdapterId> {
|
||||
match selected.checked_sub(list.len()) {
|
||||
Some(left) => {
|
||||
@ -752,7 +707,7 @@ impl Global {
|
||||
None
|
||||
}
|
||||
None => {
|
||||
let adapter = Adapter::new(list.swap_remove(*selected));
|
||||
let adapter = Adapter::<A>::new(list.swap_remove(*selected));
|
||||
log::info!("Adapter {:?} {:?}", A::VARIANT, adapter.raw.info);
|
||||
let id = HalApi::hub(self)
|
||||
.adapters
|
||||
@ -771,26 +726,27 @@ impl Global {
|
||||
profiling::scope!("Instance::request_adapter");
|
||||
api_log!("Instance::request_adapter");
|
||||
|
||||
fn gather<A: HalApi>(
|
||||
_: A,
|
||||
instance: Option<&A::Instance>,
|
||||
fn gather(
|
||||
backend: Backend,
|
||||
instance: &Instance,
|
||||
inputs: &AdapterInputs<markers::Adapter>,
|
||||
compatible_surface: Option<&Surface>,
|
||||
force_software: bool,
|
||||
device_types: &mut Vec<wgt::DeviceType>,
|
||||
) -> (Option<Id<markers::Adapter>>, Vec<hal::ExposedAdapter<A>>) {
|
||||
let id = inputs.find(A::VARIANT);
|
||||
match (id, instance) {
|
||||
) -> (Option<Id<markers::Adapter>>, Vec<hal::DynExposedAdapter>) {
|
||||
let id = inputs.find(backend);
|
||||
match (id, instance.raw(backend)) {
|
||||
(Some(id), Some(inst)) => {
|
||||
let compatible_hal_surface =
|
||||
compatible_surface.and_then(|surface| A::surface_as_hal(surface));
|
||||
compatible_surface.and_then(|surface| surface.raw(backend));
|
||||
let mut adapters = unsafe { inst.enumerate_adapters(compatible_hal_surface) };
|
||||
if force_software {
|
||||
adapters.retain(|exposed| exposed.info.device_type == wgt::DeviceType::Cpu);
|
||||
}
|
||||
if let Some(surface) = compatible_surface {
|
||||
adapters
|
||||
.retain(|exposed| surface.get_capabilities_with_raw(exposed).is_ok());
|
||||
adapters.retain(|exposed| {
|
||||
surface.get_capabilities_with_raw(backend, exposed).is_ok()
|
||||
});
|
||||
}
|
||||
device_types.extend(adapters.iter().map(|ad| ad.info.device_type));
|
||||
(id, adapters)
|
||||
@ -812,8 +768,8 @@ impl Global {
|
||||
|
||||
#[cfg(vulkan)]
|
||||
let (id_vulkan, adapters_vk) = gather(
|
||||
hal::api::Vulkan,
|
||||
self.instance.vulkan.as_ref(),
|
||||
Backend::Vulkan,
|
||||
&self.instance,
|
||||
&inputs,
|
||||
compatible_surface,
|
||||
desc.force_fallback_adapter,
|
||||
@ -821,8 +777,8 @@ impl Global {
|
||||
);
|
||||
#[cfg(metal)]
|
||||
let (id_metal, adapters_metal) = gather(
|
||||
hal::api::Metal,
|
||||
self.instance.metal.as_ref(),
|
||||
Backend::Metal,
|
||||
&self.instance,
|
||||
&inputs,
|
||||
compatible_surface,
|
||||
desc.force_fallback_adapter,
|
||||
@ -830,8 +786,8 @@ impl Global {
|
||||
);
|
||||
#[cfg(dx12)]
|
||||
let (id_dx12, adapters_dx12) = gather(
|
||||
hal::api::Dx12,
|
||||
self.instance.dx12.as_ref(),
|
||||
Backend::Dx12,
|
||||
&self.instance,
|
||||
&inputs,
|
||||
compatible_surface,
|
||||
desc.force_fallback_adapter,
|
||||
@ -839,8 +795,8 @@ impl Global {
|
||||
);
|
||||
#[cfg(gles)]
|
||||
let (id_gl, adapters_gl) = gather(
|
||||
hal::api::Gles,
|
||||
self.instance.gl.as_ref(),
|
||||
Backend::Gl,
|
||||
&self.instance,
|
||||
&inputs,
|
||||
compatible_surface,
|
||||
desc.force_fallback_adapter,
|
||||
@ -899,19 +855,19 @@ impl Global {
|
||||
|
||||
let mut selected = preferred_gpu.unwrap_or(0);
|
||||
#[cfg(vulkan)]
|
||||
if let Some(id) = self.select(&mut selected, id_vulkan, adapters_vk) {
|
||||
if let Some(id) = self.select::<hal::api::Vulkan>(&mut selected, id_vulkan, adapters_vk) {
|
||||
return Ok(id);
|
||||
}
|
||||
#[cfg(metal)]
|
||||
if let Some(id) = self.select(&mut selected, id_metal, adapters_metal) {
|
||||
if let Some(id) = self.select::<hal::api::Metal>(&mut selected, id_metal, adapters_metal) {
|
||||
return Ok(id);
|
||||
}
|
||||
#[cfg(dx12)]
|
||||
if let Some(id) = self.select(&mut selected, id_dx12, adapters_dx12) {
|
||||
if let Some(id) = self.select::<hal::api::Dx12>(&mut selected, id_dx12, adapters_dx12) {
|
||||
return Ok(id);
|
||||
}
|
||||
#[cfg(gles)]
|
||||
if let Some(id) = self.select(&mut selected, id_gl, adapters_gl) {
|
||||
if let Some(id) = self.select::<hal::api::Gles>(&mut selected, id_gl, adapters_gl) {
|
||||
return Ok(id);
|
||||
}
|
||||
let _ = selected;
|
||||
@ -925,7 +881,7 @@ impl Global {
|
||||
/// `hal_adapter` must be created from this global internal instance handle.
|
||||
pub unsafe fn create_adapter_from_hal<A: HalApi>(
|
||||
&self,
|
||||
hal_adapter: hal::ExposedAdapter<A>,
|
||||
hal_adapter: hal::DynExposedAdapter,
|
||||
input: Option<AdapterId>,
|
||||
) -> AdapterId {
|
||||
profiling::scope!("Instance::create_adapter_from_hal");
|
||||
@ -934,13 +890,13 @@ impl Global {
|
||||
|
||||
let id = match A::VARIANT {
|
||||
#[cfg(vulkan)]
|
||||
Backend::Vulkan => fid.assign(Arc::new(Adapter::new(hal_adapter))),
|
||||
Backend::Vulkan => fid.assign(Arc::new(Adapter::<A>::new(hal_adapter))),
|
||||
#[cfg(metal)]
|
||||
Backend::Metal => fid.assign(Arc::new(Adapter::new(hal_adapter))),
|
||||
Backend::Metal => fid.assign(Arc::new(Adapter::<A>::new(hal_adapter))),
|
||||
#[cfg(dx12)]
|
||||
Backend::Dx12 => fid.assign(Arc::new(Adapter::new(hal_adapter))),
|
||||
Backend::Dx12 => fid.assign(Arc::new(Adapter::<A>::new(hal_adapter))),
|
||||
#[cfg(gles)]
|
||||
Backend::Gl => fid.assign(Arc::new(Adapter::new(hal_adapter))),
|
||||
Backend::Gl => fid.assign(Arc::new(Adapter::<A>::new(hal_adapter))),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
resource_log!("Created Adapter {:?}", id);
|
||||
@ -1076,7 +1032,7 @@ impl Global {
|
||||
pub unsafe fn create_device_from_hal<A: HalApi>(
|
||||
&self,
|
||||
adapter_id: AdapterId,
|
||||
hal_device: OpenDevice<A>,
|
||||
hal_device: hal::DynOpenDevice,
|
||||
desc: &DeviceDescriptor,
|
||||
trace_path: Option<&std::path::Path>,
|
||||
device_id_in: Option<DeviceId>,
|
||||
|
@ -30,7 +30,7 @@ const FRAME_TIMEOUT_MS: u32 = 1000;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct Presentation {
|
||||
pub(crate) device: AnyDevice,
|
||||
pub(crate) device: AnyDevice, // TODO(#5124): use device: Arc<Device>
|
||||
pub(crate) config: wgt::SurfaceConfiguration<Vec<wgt::TextureFormat>>,
|
||||
pub(crate) acquired_texture: Option<id::TextureId>,
|
||||
}
|
||||
@ -153,10 +153,9 @@ impl Global {
|
||||
|
||||
let fence = device.fence.read();
|
||||
|
||||
let suf = A::surface_as_hal(surface.as_ref());
|
||||
let suf = surface.raw(A::VARIANT).unwrap();
|
||||
let (texture_id, status) = match unsafe {
|
||||
use hal::DynSurface;
|
||||
suf.unwrap().acquire_texture(
|
||||
suf.acquire_texture(
|
||||
Some(std::time::Duration::from_millis(FRAME_TIMEOUT_MS as u64)),
|
||||
fence.as_ref(),
|
||||
)
|
||||
@ -304,7 +303,7 @@ impl Global {
|
||||
.lock()
|
||||
.textures
|
||||
.remove(texture.tracker_index());
|
||||
let suf = A::surface_as_hal(&surface);
|
||||
let suf = surface.raw(A::VARIANT).unwrap();
|
||||
let exclusive_snatch_guard = device.snatchable_lock.write();
|
||||
match texture.inner.snatch(exclusive_snatch_guard).unwrap() {
|
||||
resource::TextureInner::Surface { raw, parent_id } => {
|
||||
@ -312,7 +311,7 @@ impl Global {
|
||||
log::error!("Presented frame is from a different surface");
|
||||
Err(hal::SurfaceError::Lost)
|
||||
} else {
|
||||
unsafe { queue.raw().present(suf.unwrap(), raw) }
|
||||
unsafe { queue.raw().present(suf, raw) }
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
@ -379,12 +378,11 @@ impl Global {
|
||||
.lock()
|
||||
.textures
|
||||
.remove(texture.tracker_index());
|
||||
let suf = A::surface_as_hal(&surface);
|
||||
let suf = surface.raw(A::VARIANT);
|
||||
let exclusive_snatch_guard = device.snatchable_lock.write();
|
||||
match texture.inner.snatch(exclusive_snatch_guard).unwrap() {
|
||||
resource::TextureInner::Surface { raw, parent_id } => {
|
||||
if surface_id == parent_id {
|
||||
use hal::DynSurface;
|
||||
unsafe { suf.unwrap().discard_texture(raw) };
|
||||
} else {
|
||||
log::warn!("Surface texture is outdated");
|
||||
|
@ -1271,7 +1271,10 @@ impl Global {
|
||||
|
||||
let hub = A::hub(self);
|
||||
let adapter = hub.adapters.get(id).ok();
|
||||
let hal_adapter = adapter.as_ref().map(|adapter| &adapter.raw.adapter);
|
||||
let hal_adapter = adapter
|
||||
.as_ref()
|
||||
.map(|adapter| &adapter.raw.adapter)
|
||||
.and_then(|adapter| adapter.as_any().downcast_ref());
|
||||
|
||||
hal_adapter_callback(hal_adapter)
|
||||
}
|
||||
@ -1328,7 +1331,8 @@ impl Global {
|
||||
let surface = self.surfaces.get(id).ok();
|
||||
let hal_surface = surface
|
||||
.as_ref()
|
||||
.and_then(|surface| A::surface_as_hal(surface));
|
||||
.and_then(|surface| surface.raw(A::VARIANT))
|
||||
.and_then(|surface| surface.as_any().downcast_ref());
|
||||
|
||||
hal_surface_callback(hal_surface)
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
use crate::{Adapter, DeviceError, SurfaceCapabilities, TextureFormatCapabilities};
|
||||
use crate::{
|
||||
Adapter, Api, DeviceError, OpenDevice, SurfaceCapabilities, TextureFormatCapabilities,
|
||||
};
|
||||
|
||||
use super::{DynDevice, DynQueue, DynResource, DynResourceExt, DynSurface};
|
||||
|
||||
@ -7,6 +9,15 @@ pub struct DynOpenDevice {
|
||||
pub queue: Box<dyn DynQueue>,
|
||||
}
|
||||
|
||||
impl<A: Api> From<OpenDevice<A>> for DynOpenDevice {
|
||||
fn from(open_device: OpenDevice<A>) -> Self {
|
||||
Self {
|
||||
device: Box::new(open_device.device),
|
||||
queue: Box::new(open_device.queue),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait DynAdapter: DynResource {
|
||||
unsafe fn open(
|
||||
&self,
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Box casts are needed, alternative would be a temporaries which are more verbose and not more expressive.
|
||||
#![allow(trivial_casts)]
|
||||
|
||||
use crate::{Capabilities, Instance, InstanceError};
|
||||
use crate::{Api, Capabilities, ExposedAdapter, Instance, InstanceError};
|
||||
|
||||
use super::{DynAdapter, DynResource, DynResourceExt as _, DynSurface};
|
||||
|
||||
@ -12,6 +12,17 @@ pub struct DynExposedAdapter {
|
||||
pub capabilities: Capabilities,
|
||||
}
|
||||
|
||||
impl<A: Api> From<ExposedAdapter<A>> for DynExposedAdapter {
|
||||
fn from(exposed_adapter: ExposedAdapter<A>) -> Self {
|
||||
Self {
|
||||
adapter: Box::new(exposed_adapter.adapter),
|
||||
info: exposed_adapter.info,
|
||||
features: exposed_adapter.features,
|
||||
capabilities: exposed_adapter.capabilities,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait DynInstance: DynResource {
|
||||
unsafe fn create_surface(
|
||||
&self,
|
||||
|
@ -72,7 +72,10 @@ impl ContextWgpuCore {
|
||||
&self,
|
||||
hal_adapter: hal::ExposedAdapter<A>,
|
||||
) -> wgc::id::AdapterId {
|
||||
unsafe { self.0.create_adapter_from_hal(hal_adapter, None) }
|
||||
unsafe {
|
||||
self.0
|
||||
.create_adapter_from_hal::<A>(hal_adapter.into(), None)
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn adapter_as_hal<
|
||||
@ -109,9 +112,9 @@ impl ContextWgpuCore {
|
||||
log::error!("Feature 'trace' has been removed temporarily, see https://github.com/gfx-rs/wgpu/issues/5974");
|
||||
}
|
||||
let (device_id, queue_id, error) = unsafe {
|
||||
self.0.create_device_from_hal(
|
||||
self.0.create_device_from_hal::<A>(
|
||||
*adapter,
|
||||
hal_device,
|
||||
hal_device.into(),
|
||||
&desc.map_label(|l| l.map(Borrowed)),
|
||||
None,
|
||||
None,
|
||||
|
Loading…
Reference in New Issue
Block a user