mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-26 12:20:56 +00:00
Bug 1924042 - Fallback to readback when creating Texture with ExternalTextureD3D11 is failed r=webgpu-reviewers,nical
ExternalTexture usage does not handle a case that creating texture with ExternalTexture is failed. In this case, it seems better to fallback to readback. Differential Revision: https://phabricator.services.mozilla.com/D225327
This commit is contained in:
parent
5319e76bba
commit
a9c3f28055
@ -43,6 +43,13 @@ extern bool wgpu_server_use_external_texture_for_swap_chain(
|
||||
return parent->UseExternalTextureForSwapChain(aSwapChainId);
|
||||
}
|
||||
|
||||
extern void wgpu_server_disable_external_texture_for_swap_chain(
|
||||
void* aParam, WGPUSwapChainId aSwapChainId) {
|
||||
auto* parent = static_cast<WebGPUParent*>(aParam);
|
||||
|
||||
parent->DisableExternalTextureForSwapChain(aSwapChainId);
|
||||
}
|
||||
|
||||
extern bool wgpu_server_ensure_external_texture_for_swap_chain(
|
||||
void* aParam, WGPUSwapChainId aSwapChainId, WGPUDeviceId aDeviceId,
|
||||
WGPUTextureId aTextureId, uint32_t aWidth, uint32_t aHeight,
|
||||
@ -221,7 +228,7 @@ class PresentationData {
|
||||
|
||||
public:
|
||||
WeakPtr<WebGPUParent> mParent;
|
||||
const bool mUseExternalTextureInSwapChain;
|
||||
bool mUseExternalTextureInSwapChain;
|
||||
const RawId mDeviceId;
|
||||
const RawId mQueueId;
|
||||
const layers::RGBDescriptor mDesc;
|
||||
@ -1528,7 +1535,7 @@ bool WebGPUParent::UseExternalTextureForSwapChain(
|
||||
const auto& lookup = mPresentationDataMap.find(ownerId);
|
||||
if (lookup == mPresentationDataMap.end()) {
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
||||
return IPC_OK();
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<PresentationData> data = lookup->second.get();
|
||||
@ -1536,6 +1543,25 @@ bool WebGPUParent::UseExternalTextureForSwapChain(
|
||||
return data->mUseExternalTextureInSwapChain;
|
||||
}
|
||||
|
||||
void WebGPUParent::DisableExternalTextureForSwapChain(
|
||||
ffi::WGPUSwapChainId aSwapChainId) {
|
||||
auto ownerId = layers::RemoteTextureOwnerId{aSwapChainId._0};
|
||||
const auto& lookup = mPresentationDataMap.find(ownerId);
|
||||
if (lookup == mPresentationDataMap.end()) {
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<PresentationData> data = lookup->second.get();
|
||||
|
||||
if (data->mUseExternalTextureInSwapChain) {
|
||||
gfxCriticalNote << "Disable ExternalTexture for SwapChain: "
|
||||
<< aSwapChainId._0;
|
||||
}
|
||||
|
||||
data->mUseExternalTextureInSwapChain = false;
|
||||
}
|
||||
|
||||
bool WebGPUParent::EnsureExternalTextureForSwapChain(
|
||||
ffi::WGPUSwapChainId aSwapChainId, ffi::WGPUDeviceId aDeviceId,
|
||||
ffi::WGPUTextureId aTextureId, uint32_t aWidth, uint32_t aHeight,
|
||||
|
@ -151,6 +151,8 @@ class WebGPUParent final : public PWebGPUParent, public SupportsWeakPtr {
|
||||
|
||||
bool UseExternalTextureForSwapChain(ffi::WGPUSwapChainId aSwapChainId);
|
||||
|
||||
void DisableExternalTextureForSwapChain(ffi::WGPUSwapChainId aSwapChainId);
|
||||
|
||||
bool EnsureExternalTextureForSwapChain(ffi::WGPUSwapChainId aSwapChainId,
|
||||
ffi::WGPUDeviceId aDeviceId,
|
||||
ffi::WGPUTextureId aTextureId,
|
||||
|
@ -19,11 +19,13 @@ use wgh::Instance;
|
||||
use std::borrow::Cow;
|
||||
#[allow(unused_imports)]
|
||||
use std::mem;
|
||||
use std::os::raw::c_void;
|
||||
use std::os::raw::{c_char, c_void};
|
||||
use std::ptr;
|
||||
use std::slice;
|
||||
use std::sync::atomic::{AtomicU32, Ordering};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use std::ffi::CString;
|
||||
use std::ffi::{c_long, c_ulong};
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
@ -721,12 +723,19 @@ pub extern "C" fn wgpu_vkimage_get_dma_buf_info(handle: &VkImageHandle) -> DMABu
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
#[allow(dead_code)]
|
||||
fn gfx_critical_note(msg: *const c_char);
|
||||
#[allow(dead_code)]
|
||||
fn wgpu_server_use_external_texture_for_swap_chain(
|
||||
param: *mut c_void,
|
||||
swap_chain_id: SwapChainId,
|
||||
) -> bool;
|
||||
#[allow(dead_code)]
|
||||
fn wgpu_server_disable_external_texture_for_swap_chain(
|
||||
param: *mut c_void,
|
||||
swap_chain_id: SwapChainId,
|
||||
);
|
||||
#[allow(dead_code)]
|
||||
fn wgpu_server_ensure_external_texture_for_swap_chain(
|
||||
param: *mut c_void,
|
||||
swap_chain_id: SwapChainId,
|
||||
@ -753,6 +762,98 @@ extern "C" {
|
||||
}
|
||||
|
||||
impl Global {
|
||||
#[cfg(target_os = "windows")]
|
||||
fn create_texture_with_external_texture_d3d11(
|
||||
&self,
|
||||
device_id: id::DeviceId,
|
||||
texture_id: id::TextureId,
|
||||
desc: &wgc::resource::TextureDescriptor,
|
||||
swap_chain_id: Option<SwapChainId>,
|
||||
) -> bool {
|
||||
let dx12_device = unsafe {
|
||||
self.device_as_hal::<wgc::api::Dx12, _, Option<Direct3D12::ID3D12Device>>(
|
||||
device_id,
|
||||
|hal_device| {
|
||||
if hal_device.is_none() {
|
||||
return None;
|
||||
}
|
||||
hal_device.map(|hal_device| hal_device.raw_device().clone())
|
||||
},
|
||||
)
|
||||
};
|
||||
|
||||
if dx12_device.is_none() {
|
||||
let msg = CString::new(format!("dx12 device is none")).unwrap();
|
||||
unsafe {
|
||||
gfx_critical_note(msg.as_ptr());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
let dx12_device = dx12_device.unwrap();
|
||||
let ret = unsafe {
|
||||
wgpu_server_ensure_external_texture_for_swap_chain(
|
||||
self.owner,
|
||||
swap_chain_id.unwrap(),
|
||||
device_id,
|
||||
texture_id,
|
||||
desc.size.width,
|
||||
desc.size.height,
|
||||
desc.format,
|
||||
desc.usage,
|
||||
)
|
||||
};
|
||||
if ret != true {
|
||||
let msg = CString::new(format!("Failed to create external texture")).unwrap();
|
||||
unsafe {
|
||||
gfx_critical_note(msg.as_ptr());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
let handle = unsafe { wgpu_server_get_external_texture_handle(self.owner, texture_id) };
|
||||
if handle.is_null() {
|
||||
let msg = CString::new(format!("Failed to get external texture handle")).unwrap();
|
||||
unsafe {
|
||||
gfx_critical_note(msg.as_ptr());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
let mut resource: Option<Direct3D12::ID3D12Resource> = None;
|
||||
let res =
|
||||
unsafe { dx12_device.OpenSharedHandle(Foundation::HANDLE(handle), &mut resource) };
|
||||
if res.is_err() || resource.is_none() {
|
||||
let msg = CString::new(format!("Failed to open shared handle")).unwrap();
|
||||
unsafe {
|
||||
gfx_critical_note(msg.as_ptr());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
let hal_texture = unsafe {
|
||||
<wgh::api::Dx12 as wgh::Api>::Device::texture_from_raw(
|
||||
resource.unwrap(),
|
||||
wgt::TextureFormat::Bgra8Unorm,
|
||||
wgt::TextureDimension::D2,
|
||||
desc.size,
|
||||
1,
|
||||
1,
|
||||
)
|
||||
};
|
||||
let (_, error) = unsafe {
|
||||
self.create_texture_from_hal(Box::new(hal_texture), device_id, &desc, Some(texture_id))
|
||||
};
|
||||
if let Some(err) = error {
|
||||
let msg = CString::new(format!("create_texture_from_hal() failed: {:?}", err)).unwrap();
|
||||
unsafe {
|
||||
gfx_critical_note(msg.as_ptr());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn device_action(
|
||||
&self,
|
||||
self_id: id::DeviceId,
|
||||
@ -775,98 +876,36 @@ impl Global {
|
||||
return;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let use_external_texture = if swap_chain_id.is_some() {
|
||||
unsafe {
|
||||
wgpu_server_use_external_texture_for_swap_chain(
|
||||
self.owner,
|
||||
swap_chain_id.unwrap(),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
false
|
||||
};
|
||||
let use_external_texture = if swap_chain_id.is_some() {
|
||||
unsafe {
|
||||
wgpu_server_use_external_texture_for_swap_chain(
|
||||
self.owner,
|
||||
swap_chain_id.unwrap(),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if use_external_texture {
|
||||
let dx12_device = unsafe {
|
||||
self.device_as_hal::<wgc::api::Dx12, _, Option<Direct3D12::ID3D12Device>>(
|
||||
self_id,
|
||||
|hal_device| {
|
||||
hal_device.map(|hal_device| hal_device.raw_device().clone())
|
||||
},
|
||||
)
|
||||
};
|
||||
if let Some(dx12_device) = dx12_device {
|
||||
let ret = unsafe {
|
||||
wgpu_server_ensure_external_texture_for_swap_chain(
|
||||
self.owner,
|
||||
swap_chain_id.unwrap(),
|
||||
self_id,
|
||||
id,
|
||||
desc.size.width,
|
||||
desc.size.height,
|
||||
desc.format,
|
||||
desc.usage,
|
||||
)
|
||||
};
|
||||
if ret != true {
|
||||
self.create_texture_error(Some(id), &desc);
|
||||
error_buf.init(ErrMsg {
|
||||
message: "Failed to create external texture",
|
||||
r#type: ErrorBufferType::Internal,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let handle =
|
||||
unsafe { wgpu_server_get_external_texture_handle(self.owner, id) };
|
||||
if handle.is_null() {
|
||||
self.create_texture_error(Some(id), &desc);
|
||||
error_buf.init(ErrMsg {
|
||||
message: "Failed to get external texture handle",
|
||||
r#type: ErrorBufferType::Internal,
|
||||
});
|
||||
return;
|
||||
}
|
||||
let mut resource: Option<Direct3D12::ID3D12Resource> = None;
|
||||
let res = unsafe {
|
||||
dx12_device
|
||||
.OpenSharedHandle(Foundation::HANDLE(handle), &mut resource)
|
||||
};
|
||||
if res.is_err() || resource.is_none() {
|
||||
self.create_texture_error(Some(id), &desc);
|
||||
error_buf.init(ErrMsg {
|
||||
message: "Failed to open shared handle",
|
||||
r#type: ErrorBufferType::Internal,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let hal_texture = unsafe {
|
||||
<wgh::api::Dx12 as wgh::Api>::Device::texture_from_raw(
|
||||
resource.unwrap(),
|
||||
wgt::TextureFormat::Bgra8Unorm,
|
||||
wgt::TextureDimension::D2,
|
||||
desc.size,
|
||||
1,
|
||||
1,
|
||||
)
|
||||
};
|
||||
let (_, error) = unsafe {
|
||||
self.create_texture_from_hal(
|
||||
Box::new(hal_texture),
|
||||
self_id,
|
||||
&desc,
|
||||
Some(id),
|
||||
)
|
||||
};
|
||||
if let Some(err) = error {
|
||||
error_buf.init(err);
|
||||
}
|
||||
if use_external_texture {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let is_created = self.create_texture_with_external_texture_d3d11(
|
||||
self_id,
|
||||
id,
|
||||
&desc,
|
||||
swap_chain_id,
|
||||
);
|
||||
if is_created {
|
||||
return;
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
wgpu_server_disable_external_texture_for_swap_chain(
|
||||
self.owner,
|
||||
swap_chain_id.unwrap(),
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
let (_, error) = self.device_create_texture(self_id, &desc, Some(id));
|
||||
|
Loading…
x
Reference in New Issue
Block a user