Backed out changeset 128de7e126a3 (bug 1918739) for causing wgpu_bindings related bustages CLOSED TREE

This commit is contained in:
Norisz Fay 2024-09-14 03:16:45 +03:00
Родитель 3ac3a31b8f
Коммит 12a6115875
29 изменённых файлов: 877 добавлений и 394 удалений

Просмотреть файл

@ -25,9 +25,9 @@ git = "https://github.com/franziskuskiefer/cose-rust"
rev = "43c22248d136c8b38fe42ea709d08da6355cf04b"
replace-with = "vendored-sources"
[source."git+https://github.com/gfx-rs/wgpu?rev=c8beade1877251c494036fc3661b04ec6aad63a9"]
[source."git+https://github.com/gfx-rs/wgpu?rev=c2e0ad293fc635c8695e8b2358610a5918f77695"]
git = "https://github.com/gfx-rs/wgpu"
rev = "c8beade1877251c494036fc3661b04ec6aad63a9"
rev = "c2e0ad293fc635c8695e8b2358610a5918f77695"
replace-with = "vendored-sources"
[source."git+https://github.com/hsivonen/any_all_workaround?rev=7fb1b7034c9f172aade21ee1c8554e8d8a48af80"]

8
Cargo.lock сгенерированный
Просмотреть файл

@ -4025,7 +4025,7 @@ checksum = "a2983372caf4480544083767bf2d27defafe32af49ab4df3a0b7fc90793a3664"
[[package]]
name = "naga"
version = "22.0.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=c8beade1877251c494036fc3661b04ec6aad63a9#c8beade1877251c494036fc3661b04ec6aad63a9"
source = "git+https://github.com/gfx-rs/wgpu?rev=c2e0ad293fc635c8695e8b2358610a5918f77695#c2e0ad293fc635c8695e8b2358610a5918f77695"
dependencies = [
"arrayvec",
"bit-set",
@ -6795,7 +6795,7 @@ dependencies = [
[[package]]
name = "wgpu-core"
version = "22.0.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=c8beade1877251c494036fc3661b04ec6aad63a9#c8beade1877251c494036fc3661b04ec6aad63a9"
source = "git+https://github.com/gfx-rs/wgpu?rev=c2e0ad293fc635c8695e8b2358610a5918f77695#c2e0ad293fc635c8695e8b2358610a5918f77695"
dependencies = [
"arrayvec",
"bit-vec",
@ -6820,7 +6820,7 @@ dependencies = [
[[package]]
name = "wgpu-hal"
version = "22.0.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=c8beade1877251c494036fc3661b04ec6aad63a9#c8beade1877251c494036fc3661b04ec6aad63a9"
source = "git+https://github.com/gfx-rs/wgpu?rev=c2e0ad293fc635c8695e8b2358610a5918f77695#c2e0ad293fc635c8695e8b2358610a5918f77695"
dependencies = [
"android_system_properties",
"arrayvec",
@ -6859,7 +6859,7 @@ dependencies = [
[[package]]
name = "wgpu-types"
version = "22.0.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=c8beade1877251c494036fc3661b04ec6aad63a9#c8beade1877251c494036fc3661b04ec6aad63a9"
source = "git+https://github.com/gfx-rs/wgpu?rev=c2e0ad293fc635c8695e8b2358610a5918f77695#c2e0ad293fc635c8695e8b2358610a5918f77695"
dependencies = [
"bitflags 2.6.0",
"js-sys",

Просмотреть файл

@ -59,7 +59,8 @@ already_AddRefed<Buffer> Buffer::Create(Device* aDevice, RawId aDeviceId,
const dom::GPUBufferDescriptor& aDesc,
ErrorResult& aRv) {
RefPtr<WebGPUChild> actor = aDevice->GetBridge();
RawId bufferId = ffi::wgpu_client_make_buffer_id(actor->GetClient());
RawId bufferId =
ffi::wgpu_client_make_buffer_id(actor->GetClient(), aDeviceId);
if (!aDevice->IsBridgeAlive()) {
// Create and return an invalid Buffer.

Просмотреть файл

@ -225,7 +225,7 @@ already_AddRefed<Texture> Device::CreateTexture(
ipc::ByteBuf bb;
RawId id = ffi::wgpu_client_create_texture(
mBridge->GetClient(), &desc, ownerId.ptrOr(nullptr), ToFFI(&bb));
mBridge->GetClient(), mId, &desc, ownerId.ptrOr(nullptr), ToFFI(&bb));
if (mBridge->CanSend()) {
mBridge->SendDeviceAction(mId, std::move(bb));
@ -258,8 +258,8 @@ already_AddRefed<Sampler> Device::CreateSampler(
}
ipc::ByteBuf bb;
RawId id =
ffi::wgpu_client_create_sampler(mBridge->GetClient(), &desc, ToFFI(&bb));
RawId id = ffi::wgpu_client_create_sampler(mBridge->GetClient(), mId, &desc,
ToFFI(&bb));
if (mBridge->CanSend()) {
mBridge->SendDeviceAction(mId, std::move(bb));
@ -277,7 +277,7 @@ already_AddRefed<CommandEncoder> Device::CreateCommandEncoder(
desc.label = label.Get();
ipc::ByteBuf bb;
RawId id = ffi::wgpu_client_create_command_encoder(mBridge->GetClient(),
RawId id = ffi::wgpu_client_create_command_encoder(mBridge->GetClient(), mId,
&desc, ToFFI(&bb));
if (mBridge->CanSend()) {
mBridge->SendDeviceAction(mId, std::move(bb));
@ -405,7 +405,7 @@ already_AddRefed<BindGroupLayout> Device::CreateBindGroupLayout(
ipc::ByteBuf bb;
RawId id = ffi::wgpu_client_create_bind_group_layout(mBridge->GetClient(),
&desc, ToFFI(&bb));
mId, &desc, ToFFI(&bb));
if (mBridge->CanSend()) {
mBridge->SendDeviceAction(mId, std::move(bb));
}
@ -431,7 +431,7 @@ already_AddRefed<PipelineLayout> Device::CreatePipelineLayout(
desc.bind_group_layouts_length = bindGroupLayouts.Length();
ipc::ByteBuf bb;
RawId id = ffi::wgpu_client_create_pipeline_layout(mBridge->GetClient(),
RawId id = ffi::wgpu_client_create_pipeline_layout(mBridge->GetClient(), mId,
&desc, ToFFI(&bb));
if (mBridge->CanSend()) {
mBridge->SendDeviceAction(mId, std::move(bb));
@ -479,8 +479,8 @@ already_AddRefed<BindGroup> Device::CreateBindGroup(
desc.entries_length = entries.Length();
ipc::ByteBuf bb;
RawId id = ffi::wgpu_client_create_bind_group(mBridge->GetClient(), &desc,
ToFFI(&bb));
RawId id = ffi::wgpu_client_create_bind_group(mBridge->GetClient(), mId,
&desc, ToFFI(&bb));
if (mBridge->CanSend()) {
mBridge->SendDeviceAction(mId, std::move(bb));
}
@ -619,7 +619,8 @@ already_AddRefed<ShaderModule> Device::CreateShaderModule(
return nullptr;
}
RawId moduleId = ffi::wgpu_client_make_shader_module_id(mBridge->GetClient());
RawId moduleId =
ffi::wgpu_client_make_shader_module_id(mBridge->GetClient(), mId);
RefPtr<ShaderModule> shaderModule = new ShaderModule(this, moduleId, promise);
@ -698,7 +699,7 @@ RawId CreateComputePipelineImpl(PipelineCreationContext* const aContext,
RawId implicit_bgl_ids[WGPUMAX_BIND_GROUPS] = {};
RawId id = ffi::wgpu_client_create_compute_pipeline(
aBridge->GetClient(), &desc, ToFFI(aByteBuf),
aBridge->GetClient(), aContext->mParentId, &desc, ToFFI(aByteBuf),
&aContext->mImplicitPipelineLayoutId, implicit_bgl_ids);
for (const auto& cur : implicit_bgl_ids) {
@ -869,7 +870,7 @@ RawId CreateRenderPipelineImpl(PipelineCreationContext* const aContext,
RawId implicit_bgl_ids[WGPUMAX_BIND_GROUPS] = {};
RawId id = ffi::wgpu_client_create_render_pipeline(
aBridge->GetClient(), &desc, ToFFI(aByteBuf),
aBridge->GetClient(), aContext->mParentId, &desc, ToFFI(aByteBuf),
&aContext->mImplicitPipelineLayoutId, implicit_bgl_ids);
for (const auto& cur : implicit_bgl_ids) {

Просмотреть файл

@ -202,11 +202,11 @@ already_AddRefed<RenderBundle> RenderBundleEncoder::Finish(
RawId id;
if (mValid) {
id = ffi::wgpu_client_create_render_bundle(
bridge->GetClient(), mEncoder.get(), &desc, ToFFI(&bb));
bridge->GetClient(), mEncoder.get(), deviceId, &desc, ToFFI(&bb));
} else {
id = ffi::wgpu_client_create_render_bundle_error(bridge->GetClient(),
label.Get(), ToFFI(&bb));
id = ffi::wgpu_client_create_render_bundle_error(
bridge->GetClient(), deviceId, label.Get(), ToFFI(&bb));
}
if (bridge->CanSend()) {

Просмотреть файл

@ -101,8 +101,8 @@ already_AddRefed<TextureView> Texture::CreateView(
aDesc.mArrayLayerCount.WasPassed() ? &layerCount : nullptr;
ipc::ByteBuf bb;
RawId id = ffi::wgpu_client_create_texture_view(bridge->GetClient(), &desc,
ToFFI(&bb));
RawId id = ffi::wgpu_client_create_texture_view(bridge->GetClient(), mId,
&desc, ToFFI(&bb));
if (bridge->CanSend()) {
bridge->SendTextureAction(mId, mParent->mId, std::move(bb));
}

Просмотреть файл

@ -50,7 +50,7 @@ parent:
async DeviceCreateBuffer(RawId deviceId, RawId bufferId, GPUBufferDescriptor desc, UnsafeSharedMemoryHandle shm);
async InstanceRequestAdapter(GPURequestAdapterOptions options, RawId aAdapterId) returns (ByteBuf byteBuf);
async InstanceRequestAdapter(GPURequestAdapterOptions options, RawId[] ids) returns (ByteBuf byteBuf);
async AdapterRequestDevice(
RawId adapterId,
ByteBuf descriptorBuf,

Просмотреть файл

@ -59,9 +59,17 @@ WebGPUChild::~WebGPUChild() = default;
RefPtr<AdapterPromise> WebGPUChild::InstanceRequestAdapter(
const dom::GPURequestAdapterOptions& aOptions) {
RawId id = ffi::wgpu_client_make_adapter_id(mClient.get());
const int max_ids = 10;
RawId ids[max_ids] = {0};
unsigned long count =
ffi::wgpu_client_make_adapter_ids(mClient.get(), ids, max_ids);
return SendInstanceRequestAdapter(aOptions, id)
nsTArray<RawId> sharedIds(count);
for (unsigned long i = 0; i != count; ++i) {
sharedIds.AppendElement(ids[i]);
}
return SendInstanceRequestAdapter(aOptions, sharedIds)
->Then(
GetCurrentSerialEventTarget(), __func__,
[](ipc::ByteBuf&& aInfoBuf) {
@ -82,7 +90,7 @@ RefPtr<AdapterPromise> WebGPUChild::InstanceRequestAdapter(
Maybe<DeviceRequest> WebGPUChild::AdapterRequestDevice(
RawId aSelfId, const ffi::WGPUFfiDeviceDescriptor& aDesc) {
ffi::WGPUDeviceQueueId ids =
ffi::wgpu_client_make_device_queue_id(mClient.get());
ffi::wgpu_client_make_device_queue_id(mClient.get(), aSelfId);
ByteBuf bb;
ffi::wgpu_client_serialize_device_descriptor(&aDesc, ToFFI(&bb));
@ -105,8 +113,8 @@ RawId WebGPUChild::RenderBundleEncoderFinish(
desc.label = label.Get();
ipc::ByteBuf bb;
RawId id = ffi::wgpu_client_create_render_bundle(mClient.get(), &aEncoder,
&desc, ToFFI(&bb));
RawId id = ffi::wgpu_client_create_render_bundle(
mClient.get(), &aEncoder, aDeviceId, &desc, ToFFI(&bb));
SendDeviceAction(aDeviceId, std::move(bb));
@ -119,7 +127,7 @@ RawId WebGPUChild::RenderBundleEncoderFinishError(RawId aDeviceId,
ipc::ByteBuf bb;
RawId id = ffi::wgpu_client_create_render_bundle_error(
mClient.get(), label.Get(), ToFFI(&bb));
mClient.get(), aDeviceId, label.Get(), ToFFI(&bb));
SendDeviceAction(aDeviceId, std::move(bb));
@ -190,7 +198,8 @@ void WebGPUChild::DeviceCreateSwapChain(
RawId queueId = aSelfId; // TODO: multiple queues
nsTArray<RawId> bufferIds(maxBufferCount);
for (size_t i = 0; i < maxBufferCount; ++i) {
bufferIds.AppendElement(ffi::wgpu_client_make_buffer_id(mClient.get()));
bufferIds.AppendElement(
ffi::wgpu_client_make_buffer_id(mClient.get(), aSelfId));
}
SendDeviceCreateSwapChain(aSelfId, queueId, aRgbDesc, bufferIds, aOwnerId,
aUseExternalTextureInSwapChain);
@ -211,7 +220,7 @@ void WebGPUChild::SwapChainPresent(RawId aTextureId,
const RemoteTextureOwnerId& aOwnerId) {
// Hack: the function expects `DeviceId`, but it only uses it for `backend()`
// selection.
RawId encoderId = ffi::wgpu_client_make_encoder_id(mClient.get());
RawId encoderId = ffi::wgpu_client_make_encoder_id(mClient.get(), aTextureId);
SendSwapChainPresent(aTextureId, encoderId, aRemoteTextureId, aOwnerId);
}

Просмотреть файл

@ -293,7 +293,8 @@ void WebGPUParent::ReportError(const Maybe<RawId> aDeviceId,
}
ipc::IPCResult WebGPUParent::RecvInstanceRequestAdapter(
const dom::GPURequestAdapterOptions& aOptions, RawId aAdapterId,
const dom::GPURequestAdapterOptions& aOptions,
const nsTArray<RawId>& aTargetIds,
InstanceRequestAdapterResolver&& resolver) {
ffi::WGPURequestAdapterOptions options = {};
if (aOptions.mPowerPreference.WasPassed()) {
@ -307,14 +308,15 @@ ipc::IPCResult WebGPUParent::RecvInstanceRequestAdapter(
auto luid = GetCompositorDeviceLuid();
ErrorBuffer error;
bool success = ffi::wgpu_server_instance_request_adapter(
mContext.get(), &options, aAdapterId, luid.ptrOr(nullptr), error.ToFFI());
int8_t index = ffi::wgpu_server_instance_request_adapter(
mContext.get(), &options, aTargetIds.Elements(), aTargetIds.Length(),
luid.ptrOr(nullptr), error.ToFFI());
ByteBuf infoByteBuf;
// Rust side expects an `Option`, so 0 maps to `None`.
uint64_t adapterId = 0;
if (success) {
adapterId = aAdapterId;
if (index >= 0) {
adapterId = aTargetIds[index];
}
ffi::wgpu_server_adapter_pack_info(mContext.get(), adapterId,
ToFFI(&infoByteBuf));
@ -323,8 +325,10 @@ ipc::IPCResult WebGPUParent::RecvInstanceRequestAdapter(
// free the unused IDs
ipc::ByteBuf dropByteBuf;
if (!success) {
wgpu_server_adapter_free(aAdapterId, ToFFI(&dropByteBuf));
for (size_t i = 0; i < aTargetIds.Length(); ++i) {
if (static_cast<int8_t>(i) != index) {
wgpu_server_adapter_free(aTargetIds[i], ToFFI(&dropByteBuf));
}
}
if (dropByteBuf.mData && !SendDropAction(std::move(dropByteBuf))) {
NS_ERROR("Unable to free free unused adapter IDs");

Просмотреть файл

@ -48,7 +48,8 @@ class WebGPUParent final : public PWebGPUParent, public SupportsWeakPtr {
explicit WebGPUParent();
ipc::IPCResult RecvInstanceRequestAdapter(
const dom::GPURequestAdapterOptions& aOptions, RawId aAdapterId,
const dom::GPURequestAdapterOptions& aOptions,
const nsTArray<RawId>& aTargetIds,
InstanceRequestAdapterResolver&& resolver);
ipc::IPCResult RecvAdapterRequestDevice(
RawId aAdapterId, const ipc::ByteBuf& aByteBuf, RawId aDeviceId,

Просмотреть файл

@ -17,7 +17,7 @@ default = []
[dependencies.wgc]
package = "wgpu-core"
git = "https://github.com/gfx-rs/wgpu"
rev = "c8beade1877251c494036fc3661b04ec6aad63a9"
rev = "c2e0ad293fc635c8695e8b2358610a5918f77695"
# TODO: remove the replay feature on the next update containing https://github.com/gfx-rs/wgpu/pull/5182
features = ["serde", "replay", "trace", "strict_asserts", "wgsl", "api_log_info"]
@ -26,32 +26,32 @@ features = ["serde", "replay", "trace", "strict_asserts", "wgsl", "api_log_info"
[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies.wgc]
package = "wgpu-core"
git = "https://github.com/gfx-rs/wgpu"
rev = "c8beade1877251c494036fc3661b04ec6aad63a9"
rev = "c2e0ad293fc635c8695e8b2358610a5918f77695"
features = ["metal"]
# We want the wgpu-core Direct3D backends on Windows.
[target.'cfg(windows)'.dependencies.wgc]
package = "wgpu-core"
git = "https://github.com/gfx-rs/wgpu"
rev = "c8beade1877251c494036fc3661b04ec6aad63a9"
rev = "c2e0ad293fc635c8695e8b2358610a5918f77695"
features = ["dx12"]
# We want the wgpu-core Vulkan backend on Linux and Windows.
[target.'cfg(any(windows, all(unix, not(any(target_os = "macos", target_os = "ios")))))'.dependencies.wgc]
package = "wgpu-core"
git = "https://github.com/gfx-rs/wgpu"
rev = "c8beade1877251c494036fc3661b04ec6aad63a9"
rev = "c2e0ad293fc635c8695e8b2358610a5918f77695"
features = ["vulkan"]
[dependencies.wgt]
package = "wgpu-types"
git = "https://github.com/gfx-rs/wgpu"
rev = "c8beade1877251c494036fc3661b04ec6aad63a9"
rev = "c2e0ad293fc635c8695e8b2358610a5918f77695"
[dependencies.wgh]
package = "wgpu-hal"
git = "https://github.com/gfx-rs/wgpu"
rev = "c8beade1877251c494036fc3661b04ec6aad63a9"
rev = "c2e0ad293fc635c8695e8b2358610a5918f77695"
features = ["oom_panic", "device_lost_panic", "internal_error_panic"]
[target.'cfg(windows)'.dependencies]

Просмотреть файл

@ -20,11 +20,11 @@ origin:
# Human-readable identifier for this version/release
# Generally "version NNN", "tag SSS", "bookmark SSS"
release: commit c8beade1877251c494036fc3661b04ec6aad63a9
release: c2e0ad293fc635c8695e8b2358610a5918f77695 (Thu Sep 12 15:03:04 2024 +0200)
# Revision to pull in
# Must be a long or short commit SHA (long preferred)
revision: c8beade1877251c494036fc3661b04ec6aad63a9
revision: c2e0ad293fc635c8695e8b2358610a5918f77695
license: ['MIT', 'Apache-2.0']

Просмотреть файл

@ -11,7 +11,7 @@ use crate::{
use crate::SwapChainId;
use wgc::{id, identity::IdentityManager};
use wgt::TextureFormat;
use wgt::{Backend, TextureFormat};
use wgc::id::markers;
@ -327,50 +327,87 @@ impl Default for IdentityHub {
}
impl ImplicitLayout<'_> {
fn new(identities: &IdentityHub) -> Self {
fn new(identities: &mut IdentityHub, backend: Backend) -> Self {
ImplicitLayout {
pipeline: identities.pipeline_layouts.process(),
pipeline: identities.pipeline_layouts.process(backend),
bind_groups: Cow::Owned(
(0..8) // hal::MAX_BIND_GROUPS
.map(|_| identities.bind_group_layouts.process())
.map(|_| identities.bind_group_layouts.process(backend))
.collect(),
),
}
}
}
#[derive(Debug, Default)]
struct Identities {
vulkan: IdentityHub,
#[cfg(any(target_os = "ios", target_os = "macos"))]
metal: IdentityHub,
#[cfg(windows)]
dx12: IdentityHub,
}
impl Identities {
fn select(&mut self, backend: Backend) -> &mut IdentityHub {
match backend {
Backend::Vulkan => &mut self.vulkan,
#[cfg(any(target_os = "ios", target_os = "macos"))]
Backend::Metal => &mut self.metal,
#[cfg(windows)]
Backend::Dx12 => &mut self.dx12,
_ => panic!("Unexpected backend: {:?}", backend),
}
}
}
#[derive(Debug)]
pub struct Client {
identities: Mutex<IdentityHub>,
identities: Mutex<Identities>,
}
#[no_mangle]
pub unsafe extern "C" fn wgpu_client_drop_action(client: &mut Client, byte_buf: &ByteBuf) {
let mut cursor = std::io::Cursor::new(byte_buf.as_slice());
let identities = client.identities.lock();
let mut identities = client.identities.lock();
while let Ok(action) = bincode::deserialize_from(&mut cursor) {
match action {
DropAction::Adapter(id) => identities.adapters.free(id),
DropAction::Device(id) => identities.devices.free(id),
DropAction::ShaderModule(id) => identities.shader_modules.free(id),
DropAction::PipelineLayout(id) => identities.pipeline_layouts.free(id),
DropAction::BindGroupLayout(id) => identities.bind_group_layouts.free(id),
DropAction::BindGroup(id) => identities.bind_groups.free(id),
DropAction::CommandBuffer(id) => identities.command_buffers.free(id),
DropAction::RenderBundle(id) => identities.render_bundles.free(id),
DropAction::RenderPipeline(id) => identities.render_pipelines.free(id),
DropAction::ComputePipeline(id) => identities.compute_pipelines.free(id),
DropAction::Buffer(id) => identities.buffers.free(id),
DropAction::Texture(id) => identities.textures.free(id),
DropAction::TextureView(id) => identities.texture_views.free(id),
DropAction::Sampler(id) => identities.samplers.free(id),
DropAction::Adapter(id) => identities.select(id.backend()).adapters.free(id),
DropAction::Device(id) => identities.select(id.backend()).devices.free(id),
DropAction::ShaderModule(id) => identities.select(id.backend()).shader_modules.free(id),
DropAction::PipelineLayout(id) => {
identities.select(id.backend()).pipeline_layouts.free(id)
}
DropAction::BindGroupLayout(id) => {
identities.select(id.backend()).bind_group_layouts.free(id)
}
DropAction::BindGroup(id) => identities.select(id.backend()).bind_groups.free(id),
DropAction::CommandBuffer(id) => {
identities.select(id.backend()).command_buffers.free(id)
}
DropAction::RenderBundle(id) => identities.select(id.backend()).render_bundles.free(id),
DropAction::RenderPipeline(id) => {
identities.select(id.backend()).render_pipelines.free(id)
}
DropAction::ComputePipeline(id) => {
identities.select(id.backend()).compute_pipelines.free(id)
}
DropAction::Buffer(id) => identities.select(id.backend()).buffers.free(id),
DropAction::Texture(id) => identities.select(id.backend()).textures.free(id),
DropAction::TextureView(id) => identities.select(id.backend()).texture_views.free(id),
DropAction::Sampler(id) => identities.select(id.backend()).samplers.free(id),
}
}
}
#[no_mangle]
pub extern "C" fn wgpu_client_kill_device_id(client: &Client, id: id::DeviceId) {
client.identities.lock().devices.free(id)
client
.identities
.lock()
.select(id.backend())
.devices
.free(id)
}
#[repr(C)]
@ -384,7 +421,7 @@ pub struct Infrastructure {
pub extern "C" fn wgpu_client_new() -> Infrastructure {
log::info!("Initializing WGPU client");
let client = Box::new(Client {
identities: Mutex::new(IdentityHub::default()),
identities: Mutex::new(Identities::default()),
});
Infrastructure {
client: Box::into_raw(client),
@ -403,9 +440,32 @@ pub unsafe extern "C" fn wgpu_client_delete(client: *mut Client) {
let _client = Box::from_raw(client);
}
/// # Safety
///
/// This function is unsafe as there is no guarantee that the given pointer is
/// valid for `id_length` elements.
#[no_mangle]
pub unsafe extern "C" fn wgpu_client_make_adapter_id(client: &Client) -> id::AdapterId {
client.identities.lock().adapters.process()
pub unsafe extern "C" fn wgpu_client_make_adapter_ids(
client: &Client,
ids: *mut id::AdapterId,
id_length: usize,
) -> usize {
let identities = client.identities.lock();
assert_ne!(id_length, 0);
let mut ids = std::slice::from_raw_parts_mut(ids, id_length).iter_mut();
*ids.next().unwrap() = identities.vulkan.adapters.process(Backend::Vulkan);
#[cfg(any(target_os = "ios", target_os = "macos"))]
{
*ids.next().unwrap() = identities.metal.adapters.process(Backend::Metal);
}
#[cfg(windows)]
{
*ids.next().unwrap() = identities.dx12.adapters.process(Backend::Dx12);
}
id_length - ids.len()
}
#[no_mangle]
@ -481,33 +541,55 @@ pub struct DeviceQueueId {
}
#[no_mangle]
pub extern "C" fn wgpu_client_make_device_queue_id(client: &Client) -> DeviceQueueId {
let identities = client.identities.lock();
let device = identities.devices.process();
let queue = identities.queues.process();
pub extern "C" fn wgpu_client_make_device_queue_id(
client: &Client,
adapter_id: id::AdapterId,
) -> DeviceQueueId {
let backend = adapter_id.backend();
let mut identities_guard = client.identities.lock();
let hub = identities_guard.select(backend);
let device = hub.devices.process(backend);
let queue = hub.queues.process(backend);
DeviceQueueId { device, queue }
}
#[no_mangle]
pub extern "C" fn wgpu_client_make_buffer_id(client: &Client) -> id::BufferId {
client.identities.lock().buffers.process()
pub extern "C" fn wgpu_client_make_buffer_id(
client: &Client,
device_id: id::DeviceId,
) -> id::BufferId {
let backend = device_id.backend();
client
.identities
.lock()
.select(backend)
.buffers
.process(backend)
}
#[no_mangle]
pub extern "C" fn wgpu_client_free_buffer_id(client: &Client, id: id::BufferId) {
client.identities.lock().buffers.free(id)
let backend = id.backend();
client.identities.lock().select(backend).buffers.free(id)
}
#[no_mangle]
pub extern "C" fn wgpu_client_create_texture(
client: &Client,
device_id: id::DeviceId,
desc: &wgt::TextureDescriptor<Option<&nsACString>, crate::FfiSlice<TextureFormat>>,
swap_chain_id: Option<&SwapChainId>,
bb: &mut ByteBuf,
) -> id::TextureId {
let label = wgpu_string(desc.label);
let id = client.identities.lock().textures.process();
let backend = device_id.backend();
let id = client
.identities
.lock()
.select(backend)
.textures
.process(backend);
let view_formats = unsafe { desc.view_formats.as_slice() }.to_vec();
@ -523,18 +605,26 @@ pub extern "C" fn wgpu_client_create_texture(
#[no_mangle]
pub extern "C" fn wgpu_client_free_texture_id(client: &Client, id: id::TextureId) {
client.identities.lock().textures.free(id)
let backend = id.backend();
client.identities.lock().select(backend).textures.free(id)
}
#[no_mangle]
pub extern "C" fn wgpu_client_create_texture_view(
client: &Client,
device_id: id::DeviceId,
desc: &TextureViewDescriptor,
bb: &mut ByteBuf,
) -> id::TextureViewId {
let label = wgpu_string(desc.label);
let id = client.identities.lock().texture_views.process();
let backend = device_id.backend();
let id = client
.identities
.lock()
.select(backend)
.texture_views
.process(backend);
let wgpu_desc = wgc::resource::TextureViewDescriptor {
label,
@ -556,18 +646,31 @@ pub extern "C" fn wgpu_client_create_texture_view(
#[no_mangle]
pub extern "C" fn wgpu_client_free_texture_view_id(client: &Client, id: id::TextureViewId) {
client.identities.lock().texture_views.free(id)
let backend = id.backend();
client
.identities
.lock()
.select(backend)
.texture_views
.free(id)
}
#[no_mangle]
pub extern "C" fn wgpu_client_create_sampler(
client: &Client,
device_id: id::DeviceId,
desc: &SamplerDescriptor,
bb: &mut ByteBuf,
) -> id::SamplerId {
let label = wgpu_string(desc.label);
let id = client.identities.lock().samplers.process();
let backend = device_id.backend();
let id = client
.identities
.lock()
.select(backend)
.samplers
.process(backend);
let wgpu_desc = wgc::resource::SamplerDescriptor {
label,
@ -588,24 +691,32 @@ pub extern "C" fn wgpu_client_create_sampler(
#[no_mangle]
pub extern "C" fn wgpu_client_free_sampler_id(client: &Client, id: id::SamplerId) {
client.identities.lock().samplers.free(id)
let backend = id.backend();
client.identities.lock().select(backend).samplers.free(id)
}
#[no_mangle]
pub extern "C" fn wgpu_client_make_encoder_id(client: &Client) -> id::CommandEncoderId {
pub extern "C" fn wgpu_client_make_encoder_id(
client: &Client,
device_id: id::DeviceId,
) -> id::CommandEncoderId {
let backend = device_id.backend();
client
.identities
.lock()
.select(backend)
.command_buffers
.process()
.process(backend)
.into_command_encoder_id()
}
#[no_mangle]
pub extern "C" fn wgpu_client_free_command_encoder_id(client: &Client, id: id::CommandEncoderId) {
let backend = id.backend();
client
.identities
.lock()
.select(backend)
.command_buffers
.free(id.into_command_buffer_id())
}
@ -613,16 +724,19 @@ pub extern "C" fn wgpu_client_free_command_encoder_id(client: &Client, id: id::C
#[no_mangle]
pub extern "C" fn wgpu_client_create_command_encoder(
client: &Client,
device_id: id::DeviceId,
desc: &wgt::CommandEncoderDescriptor<Option<&nsACString>>,
bb: &mut ByteBuf,
) -> id::CommandEncoderId {
let label = wgpu_string(desc.label);
let backend = device_id.backend();
let id = client
.identities
.lock()
.select(backend)
.command_buffers
.process()
.process(backend)
.into_command_encoder_id();
let action = DeviceAction::CreateCommandEncoder(id, desc.map_label(|_| label));
@ -682,12 +796,19 @@ pub unsafe extern "C" fn wgpu_render_bundle_encoder_destroy(
pub unsafe extern "C" fn wgpu_client_create_render_bundle(
client: &Client,
encoder: *mut wgc::command::RenderBundleEncoder,
device_id: id::DeviceId,
desc: &wgt::RenderBundleDescriptor<Option<&nsACString>>,
bb: &mut ByteBuf,
) -> id::RenderBundleId {
let label = wgpu_string(desc.label);
let id = client.identities.lock().render_bundles.process();
let backend = device_id.backend();
let id = client
.identities
.lock()
.select(backend)
.render_bundles
.process(backend);
let action =
DeviceAction::CreateRenderBundle(id, *Box::from_raw(encoder), desc.map_label(|_| label));
@ -698,12 +819,19 @@ pub unsafe extern "C" fn wgpu_client_create_render_bundle(
#[no_mangle]
pub unsafe extern "C" fn wgpu_client_create_render_bundle_error(
client: &Client,
device_id: id::DeviceId,
label: Option<&nsACString>,
bb: &mut ByteBuf,
) -> id::RenderBundleId {
let label = wgpu_string(label);
let id = client.identities.lock().render_bundles.process();
let backend = device_id.backend();
let id = client
.identities
.lock()
.select(backend)
.render_bundles
.process(backend);
let action = DeviceAction::CreateRenderBundleError(id, label);
*bb = make_byte_buf(&action);
@ -712,7 +840,13 @@ pub unsafe extern "C" fn wgpu_client_create_render_bundle_error(
#[no_mangle]
pub extern "C" fn wgpu_client_free_render_bundle_id(client: &Client, id: id::RenderBundleId) {
client.identities.lock().render_bundles.free(id)
let backend = id.backend();
client
.identities
.lock()
.select(backend)
.render_bundles
.free(id)
}
#[repr(C)]
@ -849,12 +983,19 @@ pub unsafe extern "C" fn wgpu_render_pass_destroy(pass: *mut crate::command::Rec
#[no_mangle]
pub unsafe extern "C" fn wgpu_client_create_bind_group_layout(
client: &Client,
device_id: id::DeviceId,
desc: &BindGroupLayoutDescriptor,
bb: &mut ByteBuf,
) -> id::BindGroupLayoutId {
let label = wgpu_string(desc.label);
let id = client.identities.lock().bind_group_layouts.process();
let backend = device_id.backend();
let id = client
.identities
.lock()
.select(backend)
.bind_group_layouts
.process(backend);
let mut entries = Vec::with_capacity(desc.entries_length);
for entry in make_slice(desc.entries, desc.entries_length) {
@ -936,7 +1077,13 @@ pub extern "C" fn wgpu_client_free_bind_group_layout_id(
client: &Client,
id: id::BindGroupLayoutId,
) {
client.identities.lock().bind_group_layouts.free(id)
let backend = id.backend();
client
.identities
.lock()
.select(backend)
.bind_group_layouts
.free(id)
}
#[no_mangle]
@ -946,7 +1093,13 @@ pub unsafe extern "C" fn wgpu_client_render_pipeline_get_bind_group_layout(
index: u32,
bb: &mut ByteBuf,
) -> id::BindGroupLayoutId {
let bgl_id = client.identities.lock().bind_group_layouts.process();
let backend = pipeline_id.backend();
let bgl_id = client
.identities
.lock()
.select(backend)
.bind_group_layouts
.process(backend);
let action = DeviceAction::RenderPipelineGetBindGroupLayout(pipeline_id, index, bgl_id);
*bb = make_byte_buf(&action);
@ -961,7 +1114,13 @@ pub unsafe extern "C" fn wgpu_client_compute_pipeline_get_bind_group_layout(
index: u32,
bb: &mut ByteBuf,
) -> id::BindGroupLayoutId {
let bgl_id = client.identities.lock().bind_group_layouts.process();
let backend = pipeline_id.backend();
let bgl_id = client
.identities
.lock()
.select(backend)
.bind_group_layouts
.process(backend);
let action = DeviceAction::ComputePipelineGetBindGroupLayout(pipeline_id, index, bgl_id);
*bb = make_byte_buf(&action);
@ -972,12 +1131,19 @@ pub unsafe extern "C" fn wgpu_client_compute_pipeline_get_bind_group_layout(
#[no_mangle]
pub unsafe extern "C" fn wgpu_client_create_pipeline_layout(
client: &Client,
device_id: id::DeviceId,
desc: &PipelineLayoutDescriptor,
bb: &mut ByteBuf,
) -> id::PipelineLayoutId {
let label = wgpu_string(desc.label);
let id = client.identities.lock().pipeline_layouts.process();
let backend = device_id.backend();
let id = client
.identities
.lock()
.select(backend)
.pipeline_layouts
.process(backend);
let wgpu_desc = wgc::binding_model::PipelineLayoutDescriptor {
label,
@ -995,18 +1161,31 @@ pub unsafe extern "C" fn wgpu_client_create_pipeline_layout(
#[no_mangle]
pub extern "C" fn wgpu_client_free_pipeline_layout_id(client: &Client, id: id::PipelineLayoutId) {
client.identities.lock().pipeline_layouts.free(id)
let backend = id.backend();
client
.identities
.lock()
.select(backend)
.pipeline_layouts
.free(id)
}
#[no_mangle]
pub unsafe extern "C" fn wgpu_client_create_bind_group(
client: &Client,
device_id: id::DeviceId,
desc: &BindGroupDescriptor,
bb: &mut ByteBuf,
) -> id::BindGroupId {
let label = wgpu_string(desc.label);
let id = client.identities.lock().bind_groups.process();
let backend = device_id.backend();
let id = client
.identities
.lock()
.select(backend)
.bind_groups
.process(backend);
let mut entries = Vec::with_capacity(desc.entries_length);
for entry in make_slice(desc.entries, desc.entries_length) {
@ -1040,22 +1219,44 @@ pub unsafe extern "C" fn wgpu_client_create_bind_group(
#[no_mangle]
pub extern "C" fn wgpu_client_free_bind_group_id(client: &Client, id: id::BindGroupId) {
client.identities.lock().bind_groups.free(id)
let backend = id.backend();
client
.identities
.lock()
.select(backend)
.bind_groups
.free(id)
}
#[no_mangle]
pub extern "C" fn wgpu_client_make_shader_module_id(client: &Client) -> id::ShaderModuleId {
client.identities.lock().shader_modules.process()
pub extern "C" fn wgpu_client_make_shader_module_id(
client: &Client,
device_id: id::DeviceId,
) -> id::ShaderModuleId {
let backend = device_id.backend();
client
.identities
.lock()
.select(backend)
.shader_modules
.process(backend)
}
#[no_mangle]
pub extern "C" fn wgpu_client_free_shader_module_id(client: &Client, id: id::ShaderModuleId) {
client.identities.lock().shader_modules.free(id)
let backend = id.backend();
client
.identities
.lock()
.select(backend)
.shader_modules
.free(id)
}
#[no_mangle]
pub unsafe extern "C" fn wgpu_client_create_compute_pipeline(
client: &Client,
device_id: id::DeviceId,
desc: &ComputePipelineDescriptor,
bb: &mut ByteBuf,
implicit_pipeline_layout_id: *mut Option<id::PipelineLayoutId>,
@ -1063,8 +1264,12 @@ pub unsafe extern "C" fn wgpu_client_create_compute_pipeline(
) -> id::ComputePipelineId {
let label = wgpu_string(desc.label);
let identities = client.identities.lock();
let id = identities.compute_pipelines.process();
let backend = device_id.backend();
let mut identities = client.identities.lock();
let id = identities
.select(backend)
.compute_pipelines
.process(backend);
let wgpu_desc = wgc::pipeline::ComputePipelineDescriptor {
label,
@ -1076,7 +1281,7 @@ pub unsafe extern "C" fn wgpu_client_create_compute_pipeline(
let implicit = match desc.layout {
Some(_) => None,
None => {
let implicit = ImplicitLayout::new(&identities);
let implicit = ImplicitLayout::new(identities.select(backend), backend);
ptr::write(implicit_pipeline_layout_id, Some(implicit.pipeline));
for (i, bgl_id) in implicit.bind_groups.iter().enumerate() {
*implicit_bind_group_layout_ids.add(i) = Some(*bgl_id);
@ -1092,12 +1297,19 @@ pub unsafe extern "C" fn wgpu_client_create_compute_pipeline(
#[no_mangle]
pub extern "C" fn wgpu_client_free_compute_pipeline_id(client: &Client, id: id::ComputePipelineId) {
client.identities.lock().compute_pipelines.free(id)
let backend = id.backend();
client
.identities
.lock()
.select(backend)
.compute_pipelines
.free(id)
}
#[no_mangle]
pub unsafe extern "C" fn wgpu_client_create_render_pipeline(
client: &Client,
device_id: id::DeviceId,
desc: &RenderPipelineDescriptor,
bb: &mut ByteBuf,
implicit_pipeline_layout_id: *mut Option<id::PipelineLayoutId>,
@ -1105,8 +1317,9 @@ pub unsafe extern "C" fn wgpu_client_create_render_pipeline(
) -> id::RenderPipelineId {
let label = wgpu_string(desc.label);
let identities = client.identities.lock();
let id = identities.render_pipelines.process();
let backend = device_id.backend();
let mut identities = client.identities.lock();
let id = identities.select(backend).render_pipelines.process(backend);
let wgpu_desc = wgc::pipeline::RenderPipelineDescriptor {
label,
@ -1123,7 +1336,7 @@ pub unsafe extern "C" fn wgpu_client_create_render_pipeline(
let implicit = match desc.layout {
Some(_) => None,
None => {
let implicit = ImplicitLayout::new(&identities);
let implicit = ImplicitLayout::new(identities.select(backend), backend);
ptr::write(implicit_pipeline_layout_id, Some(implicit.pipeline));
for (i, bgl_id) in implicit.bind_groups.iter().enumerate() {
*implicit_bind_group_layout_ids.add(i) = Some(*bgl_id);
@ -1139,7 +1352,13 @@ pub unsafe extern "C" fn wgpu_client_create_render_pipeline(
#[no_mangle]
pub extern "C" fn wgpu_client_free_render_pipeline_id(client: &Client, id: id::RenderPipelineId) {
client.identities.lock().render_pipelines.free(id)
let backend = id.backend();
client
.identities
.lock()
.select(backend)
.render_pipelines
.free(id)
}
#[no_mangle]

Просмотреть файл

@ -173,10 +173,13 @@ pub struct FfiLUID {
pub unsafe extern "C" fn wgpu_server_instance_request_adapter(
global: &Global,
desc: &wgc::instance::RequestAdapterOptions,
adapter_id: id::AdapterId,
ids: *const id::AdapterId,
id_length: usize,
adapter_luid: Option<&FfiLUID>,
mut error_buf: ErrorBuffer,
) -> bool {
) -> i8 {
let ids = slice::from_raw_parts(ids, id_length);
// Prefer to use the dx12 backend, if one exists, and use the same DXGI adapter as WebRender.
// If wgpu uses a different adapter than WebRender, textures created by
// webgpu::ExternalTexture do not work with wgpu.
@ -187,14 +190,18 @@ pub unsafe extern "C" fn wgpu_server_instance_request_adapter(
let raw_adapter = adapter.adapter.raw_adapter();
let desc = unsafe { raw_adapter.GetDesc() };
if let Ok(desc) = desc {
if desc.AdapterLuid.LowPart == adapter_luid.unwrap().low_part
let id = ids
.iter()
.find_map(|id| (id.backend() == wgt::Backend::Dx12).then_some(id));
if id.is_some()
&& desc.AdapterLuid.LowPart == adapter_luid.unwrap().low_part
&& desc.AdapterLuid.HighPart == adapter_luid.unwrap().high_part
{
global.create_adapter_from_hal(
let adapter_id = global.create_adapter_from_hal(
wgh::DynExposedAdapter::from(adapter),
Some(adapter_id),
Some(id.unwrap().clone()),
);
return true;
return ids.iter().position(|&i| i == adapter_id).unwrap() as i8;
}
}
}
@ -202,15 +209,15 @@ pub unsafe extern "C" fn wgpu_server_instance_request_adapter(
message: "Failed to create adapter for dx12",
r#type: ErrorBufferType::Internal,
});
return false;
return -1;
}
}
match global.request_adapter(desc, wgt::Backends::PRIMARY, Some(adapter_id)) {
Ok(id) => return true,
match global.request_adapter(desc, wgc::instance::AdapterInputs::IdSet(ids)) {
Ok(id) => ids.iter().position(|&i| i == id).unwrap() as i8,
Err(e) => {
error_buf.init(e);
return false;
-1
}
}
}
@ -248,7 +255,7 @@ pub unsafe extern "C" fn wgpu_server_adapter_pack_info(
}
let support_use_external_texture_in_swap_chain = if cfg!(target_os = "windows") {
backend == wgt::Backend::Dx12 && is_hardware
id.backend() == wgt::Backend::Dx12 && is_hardware
} else {
false
};
@ -485,7 +492,7 @@ pub extern "C" fn wgpu_server_device_create_buffer(
message: "Out of memory",
r#type: ErrorBufferType::OutOfMemory,
});
global.create_buffer_error(Some(buffer_id), &desc);
global.create_buffer_error(buffer_id.backend(), Some(buffer_id), &desc);
return;
}
@ -588,8 +595,10 @@ pub extern "C" fn wgpu_server_get_device_fence_handle(
global: &Global,
device_id: id::DeviceId,
) -> *mut c_void {
assert!(device_id.backend() == wgt::Backend::Dx12);
#[cfg(target_os = "windows")]
{
if device_id.backend() == wgt::Backend::Dx12 {
let dx12_device = unsafe {
global.device_as_hal::<wgc::api::Dx12, _, Option<Direct3D12::ID3D12Device>>(
device_id,
@ -667,7 +676,7 @@ impl Global {
|| desc.size.height > max
|| desc.size.depth_or_array_layers > max
{
self.create_texture_error(Some(id), &desc);
self.create_texture_error(id.backend(), Some(id), &desc);
error_buf.init(ErrMsg {
message: "Out of memory",
r#type: ErrorBufferType::OutOfMemory,
@ -688,84 +697,80 @@ impl Global {
false
};
if use_external_texture {
let dx12_device = unsafe {
self.device_as_hal::<wgc::api::Dx12, _, Option<Direct3D12::ID3D12Device>>(
if use_external_texture && self_id.backend() == wgt::Backend::Dx12 {
let ret = unsafe {
wgpu_server_ensure_external_texture_for_swap_chain(
self.owner,
swap_chain_id.unwrap(),
self_id,
|hal_device| {
hal_device.map(|hal_device| hal_device.raw_device().clone())
},
id,
desc.size.width,
desc.size.height,
desc.format,
desc.usage,
)
};
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 ret != true {
self.create_texture_error(id.backend(), Some(id), &desc);
error_buf.init(ErrMsg {
message: "Failed to create external texture",
r#type: ErrorBufferType::Internal,
});
return;
}
let dx12_device = unsafe {
self.device_as_hal::<wgc::api::Dx12, _, Direct3D12::ID3D12Device>(
self_id,
|hal_device| hal_device.unwrap().raw_device().clone(),
)
};
let handle =
unsafe { wgpu_server_get_external_texture_handle(self.owner, id) };
if handle.is_null() {
self.create_texture_error(id.backend(), 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(id.backend(), 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);
}
return;
}
}
@ -853,6 +858,7 @@ impl Global {
}
DeviceAction::CreateRenderBundleError(buffer_id, label) => {
self.create_render_bundle_error(
buffer_id.backend(),
Some(buffer_id),
&wgt::RenderBundleDescriptor { label },
);

Просмотреть файл

@ -3127,12 +3127,12 @@ delta = "0.20.0 -> 22.0.0"
[[audits.naga]]
who = [
"Teodor Tanasoaia <ttanasoaia@mozilla.com>",
"Erich Gubler <erichdongubler@gmail.com>",
"Jim Blandy <jimb@red-bean.com>",
"Teodor Tanasoaia <ttanasoaia@mozilla.com>",
]
criteria = "safe-to-deploy"
delta = "22.0.0 -> 22.0.0@git:c8beade1877251c494036fc3661b04ec6aad63a9"
delta = "22.0.0 -> 22.0.0@git:c2e0ad293fc635c8695e8b2358610a5918f77695"
importable = false
[[audits.net2]]
@ -5116,12 +5116,12 @@ delta = "0.20.0 -> 22.0.0"
[[audits.wgpu-core]]
who = [
"Teodor Tanasoaia <ttanasoaia@mozilla.com>",
"Erich Gubler <erichdongubler@gmail.com>",
"Jim Blandy <jimb@red-bean.com>",
"Teodor Tanasoaia <ttanasoaia@mozilla.com>",
]
criteria = "safe-to-deploy"
delta = "22.0.0 -> 22.0.0@git:c8beade1877251c494036fc3661b04ec6aad63a9"
delta = "22.0.0 -> 22.0.0@git:c2e0ad293fc635c8695e8b2358610a5918f77695"
importable = false
[[audits.wgpu-hal]]
@ -5189,12 +5189,12 @@ delta = "0.20.0 -> 22.0.0"
[[audits.wgpu-hal]]
who = [
"Teodor Tanasoaia <ttanasoaia@mozilla.com>",
"Erich Gubler <erichdongubler@gmail.com>",
"Jim Blandy <jimb@red-bean.com>",
"Teodor Tanasoaia <ttanasoaia@mozilla.com>",
]
criteria = "safe-to-deploy"
delta = "22.0.0 -> 22.0.0@git:c8beade1877251c494036fc3661b04ec6aad63a9"
delta = "22.0.0 -> 22.0.0@git:c2e0ad293fc635c8695e8b2358610a5918f77695"
importable = false
[[audits.wgpu-types]]
@ -5262,12 +5262,12 @@ delta = "0.20.0 -> 22.0.0"
[[audits.wgpu-types]]
who = [
"Teodor Tanasoaia <ttanasoaia@mozilla.com>",
"Erich Gubler <erichdongubler@gmail.com>",
"Jim Blandy <jimb@red-bean.com>",
"Teodor Tanasoaia <ttanasoaia@mozilla.com>",
]
criteria = "safe-to-deploy"
delta = "22.0.0 -> 22.0.0@git:c8beade1877251c494036fc3661b04ec6aad63a9"
delta = "22.0.0 -> 22.0.0@git:c2e0ad293fc635c8695e8b2358610a5918f77695"
importable = false
[[audits.whatsys]]

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -104,7 +104,7 @@ impl Global {
profiling::scope!("Device::create_buffer");
let hub = &self.hub;
let fid = hub.buffers.prepare(id_in);
let fid = hub.buffers.prepare(device_id.backend(), id_in);
let error = 'error: {
let device = self.hub.devices.get(device_id);
@ -175,19 +175,21 @@ impl Global {
/// [`wgpu_types::BufferUsages`]: wgt::BufferUsages
pub fn create_buffer_error(
&self,
backend: wgt::Backend,
id_in: Option<id::BufferId>,
desc: &resource::BufferDescriptor,
) {
let fid = self.hub.buffers.prepare(id_in);
let fid = self.hub.buffers.prepare(backend, id_in);
fid.assign(Fallible::Invalid(Arc::new(desc.label.to_string())));
}
pub fn create_render_bundle_error(
&self,
backend: wgt::Backend,
id_in: Option<id::RenderBundleId>,
desc: &command::RenderBundleDescriptor,
) {
let fid = self.hub.render_bundles.prepare(id_in);
let fid = self.hub.render_bundles.prepare(backend, id_in);
fid.assign(Fallible::Invalid(Arc::new(desc.label.to_string())));
}
@ -196,10 +198,11 @@ impl Global {
/// See `create_buffer_error` for more context and explanation.
pub fn create_texture_error(
&self,
backend: wgt::Backend,
id_in: Option<id::TextureId>,
desc: &resource::TextureDescriptor,
) {
let fid = self.hub.textures.prepare(id_in);
let fid = self.hub.textures.prepare(backend, id_in);
fid.assign(Fallible::Invalid(Arc::new(desc.label.to_string())));
}
@ -308,7 +311,7 @@ impl Global {
let hub = &self.hub;
let fid = hub.textures.prepare(id_in);
let fid = hub.textures.prepare(device_id.backend(), id_in);
let error = 'error: {
let device = self.hub.devices.get(device_id);
@ -351,7 +354,7 @@ impl Global {
let hub = &self.hub;
let fid = hub.textures.prepare(id_in);
let fid = hub.textures.prepare(device_id.backend(), id_in);
let error = 'error: {
let device = self.hub.devices.get(device_id);
@ -395,7 +398,7 @@ impl Global {
profiling::scope!("Device::create_buffer");
let hub = &self.hub;
let fid = hub.buffers.prepare(id_in);
let fid = hub.buffers.prepare(A::VARIANT, id_in);
let device = self.hub.devices.get(device_id);
@ -455,7 +458,7 @@ impl Global {
let hub = &self.hub;
let fid = hub.texture_views.prepare(id_in);
let fid = hub.texture_views.prepare(texture_id.backend(), id_in);
let error = 'error: {
let texture = match hub.textures.get(texture_id).get() {
@ -519,7 +522,7 @@ impl Global {
profiling::scope!("Device::create_sampler");
let hub = &self.hub;
let fid = hub.samplers.prepare(id_in);
let fid = hub.samplers.prepare(device_id.backend(), id_in);
let error = 'error: {
let device = self.hub.devices.get(device_id);
@ -572,7 +575,7 @@ impl Global {
profiling::scope!("Device::create_bind_group_layout");
let hub = &self.hub;
let fid = hub.bind_group_layouts.prepare(id_in);
let fid = hub.bind_group_layouts.prepare(device_id.backend(), id_in);
let error = 'error: {
let device = self.hub.devices.get(device_id);
@ -644,7 +647,7 @@ impl Global {
profiling::scope!("Device::create_pipeline_layout");
let hub = &self.hub;
let fid = hub.pipeline_layouts.prepare(id_in);
let fid = hub.pipeline_layouts.prepare(device_id.backend(), id_in);
let error = 'error: {
let device = self.hub.devices.get(device_id);
@ -712,7 +715,7 @@ impl Global {
profiling::scope!("Device::create_bind_group");
let hub = &self.hub;
let fid = hub.bind_groups.prepare(id_in);
let fid = hub.bind_groups.prepare(device_id.backend(), id_in);
let error = 'error: {
let device = self.hub.devices.get(device_id);
@ -874,7 +877,7 @@ impl Global {
profiling::scope!("Device::create_shader_module");
let hub = &self.hub;
let fid = hub.shader_modules.prepare(id_in);
let fid = hub.shader_modules.prepare(device_id.backend(), id_in);
let error = 'error: {
let device = self.hub.devices.get(device_id);
@ -946,7 +949,7 @@ impl Global {
profiling::scope!("Device::create_shader_module");
let hub = &self.hub;
let fid = hub.shader_modules.prepare(id_in);
let fid = hub.shader_modules.prepare(device_id.backend(), id_in);
let error = 'error: {
let device = self.hub.devices.get(device_id);
@ -1003,9 +1006,10 @@ impl Global {
profiling::scope!("Device::create_command_encoder");
let hub = &self.hub;
let fid = hub
.command_buffers
.prepare(id_in.map(|id| id.into_command_buffer_id()));
let fid = hub.command_buffers.prepare(
device_id.backend(),
id_in.map(|id| id.into_command_buffer_id()),
);
let device = self.hub.devices.get(device_id);
@ -1068,7 +1072,9 @@ impl Global {
let hub = &self.hub;
let fid = hub.render_bundles.prepare(id_in);
let fid = hub
.render_bundles
.prepare(bundle_encoder.parent().backend(), id_in);
let error = 'error: {
let device = self.hub.devices.get(bundle_encoder.parent());
@ -1127,7 +1133,7 @@ impl Global {
profiling::scope!("Device::create_query_set");
let hub = &self.hub;
let fid = hub.query_sets.prepare(id_in);
let fid = hub.query_sets.prepare(device_id.backend(), id_in);
let error = 'error: {
let device = self.hub.devices.get(device_id);
@ -1188,7 +1194,7 @@ impl Global {
let missing_implicit_pipeline_ids =
desc.layout.is_none() && id_in.is_some() && implicit_pipeline_ids.is_none();
let fid = hub.render_pipelines.prepare(id_in);
let fid = hub.render_pipelines.prepare(device_id.backend(), id_in);
let implicit_context = implicit_pipeline_ids.map(|ipi| ipi.prepare(hub));
let error = 'error: {
@ -1372,7 +1378,7 @@ impl Global {
) {
let hub = &self.hub;
let fid = hub.bind_group_layouts.prepare(id_in);
let fid = hub.bind_group_layouts.prepare(pipeline_id.backend(), id_in);
let error = 'error: {
let pipeline = match hub.render_pipelines.get(pipeline_id).get() {
@ -1425,7 +1431,7 @@ impl Global {
let missing_implicit_pipeline_ids =
desc.layout.is_none() && id_in.is_some() && implicit_pipeline_ids.is_none();
let fid = hub.compute_pipelines.prepare(id_in);
let fid = hub.compute_pipelines.prepare(device_id.backend(), id_in);
let implicit_context = implicit_pipeline_ids.map(|ipi| ipi.prepare(hub));
let error = 'error: {
@ -1556,7 +1562,7 @@ impl Global {
) {
let hub = &self.hub;
let fid = hub.bind_group_layouts.prepare(id_in);
let fid = hub.bind_group_layouts.prepare(pipeline_id.backend(), id_in);
let error = 'error: {
let pipeline = match hub.compute_pipelines.get(pipeline_id).get() {
@ -1610,7 +1616,7 @@ impl Global {
let hub = &self.hub;
let fid = hub.pipeline_caches.prepare(id_in);
let fid = hub.pipeline_caches.prepare(device_id.backend(), id_in);
let error: pipeline::CreatePipelineCacheError = 'error: {
let device = self.hub.devices.get(device_id);
@ -1875,7 +1881,7 @@ impl Global {
//
// https://github.com/gfx-rs/wgpu/issues/4105
let surface_raw = surface.raw(device.backend()).unwrap();
let surface_raw = surface.raw(device_id.backend()).unwrap();
match unsafe { surface_raw.configure(device.raw(), &hal_config) } {
Ok(()) => (),
Err(error) => {
@ -1957,6 +1963,7 @@ impl Global {
/// submissions still in flight.
fn poll_all_devices_of_api(
&self,
backend: wgt::Backend,
force_wait: bool,
closures: &mut UserClosures,
) -> Result<bool, WaitIdleError> {
@ -1967,7 +1974,7 @@ impl Global {
{
let device_guard = hub.devices.read();
for (_id, device) in device_guard.iter() {
for (_id, device) in device_guard.iter(backend) {
let maintain = if force_wait {
wgt::Maintain::Wait
} else {
@ -1997,7 +2004,28 @@ impl Global {
pub fn poll_all_devices(&self, force_wait: bool) -> Result<bool, WaitIdleError> {
api_log!("poll_all_devices");
let mut closures = UserClosures::default();
let all_queue_empty = self.poll_all_devices_of_api(force_wait, &mut closures)?;
let mut all_queue_empty = true;
#[cfg(vulkan)]
{
all_queue_empty &=
self.poll_all_devices_of_api(wgt::Backend::Vulkan, force_wait, &mut closures)?;
}
#[cfg(metal)]
{
all_queue_empty &=
self.poll_all_devices_of_api(wgt::Backend::Metal, force_wait, &mut closures)?;
}
#[cfg(dx12)]
{
all_queue_empty &=
self.poll_all_devices_of_api(wgt::Backend::Dx12, force_wait, &mut closures)?;
}
#[cfg(gles)]
{
all_queue_empty &=
self.poll_all_devices_of_api(wgt::Backend::Gl, force_wait, &mut closures)?;
}
closures.fire();

Просмотреть файл

@ -457,12 +457,16 @@ pub struct ImplicitPipelineIds<'a> {
impl ImplicitPipelineIds<'_> {
fn prepare(self, hub: &Hub) -> ImplicitPipelineContext {
let backend = self.root_id.backend();
ImplicitPipelineContext {
root_id: hub.pipeline_layouts.prepare(Some(self.root_id)).id(),
root_id: hub
.pipeline_layouts
.prepare(backend, Some(self.root_id))
.id(),
group_ids: self
.group_ids
.iter()
.map(|id_in| hub.bind_group_layouts.prepare(Some(*id_in)).id())
.map(|id_in| hub.bind_group_layouts.prepare(backend, Some(*id_in)).id())
.collect(),
}
}

Просмотреть файл

@ -444,7 +444,7 @@ impl Global {
let staging_buffer = StagingBuffer::new(device, buffer_size)?;
let ptr = unsafe { staging_buffer.ptr() };
let fid = hub.staging_buffers.prepare(id_in);
let fid = hub.staging_buffers.prepare(queue_id.backend(), id_in);
let id = fid.assign(staging_buffer);
resource_log!("Queue::create_staging_buffer {id:?}");

152
third_party/rust/wgpu-core/src/id.rs поставляемый
Просмотреть файл

@ -4,25 +4,18 @@ use std::{
fmt::{self, Debug},
hash::Hash,
marker::PhantomData,
num::NonZeroU64,
};
use wgt::WasmNotSendSync;
use wgt::{Backend, WasmNotSendSync};
const _: () = {
if std::mem::size_of::<Index>() != 4 {
panic!()
}
};
const _: () = {
if std::mem::size_of::<Epoch>() != 4 {
panic!()
}
};
const _: () = {
if std::mem::size_of::<RawId>() != 8 {
panic!()
}
};
type IdType = u64;
type ZippedIndex = Index;
type NonZeroId = std::num::NonZeroU64;
const INDEX_BITS: usize = ZippedIndex::BITS as usize;
const EPOCH_BITS: usize = INDEX_BITS - BACKEND_BITS;
const BACKEND_BITS: usize = 3;
const BACKEND_SHIFT: usize = INDEX_BITS * 2 - BACKEND_BITS;
pub const EPOCH_MASK: u32 = (1 << (EPOCH_BITS)) - 1;
/// The raw underlying representation of an identifier.
#[repr(transparent)]
@ -37,18 +30,50 @@ const _: () = {
serde(from = "SerialId")
)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct RawId(NonZeroU64);
pub struct RawId(NonZeroId);
impl RawId {
#[doc(hidden)]
#[inline]
pub fn from_non_zero(non_zero: NonZeroId) -> Self {
Self(non_zero)
}
#[doc(hidden)]
#[inline]
pub fn into_non_zero(self) -> NonZeroId {
self.0
}
/// Zip together an identifier and return its raw underlying representation.
pub fn zip(index: Index, epoch: Epoch) -> RawId {
let v = (index as u64) | ((epoch as u64) << 32);
Self(NonZeroU64::new(v).unwrap())
pub fn zip(index: Index, epoch: Epoch, backend: Backend) -> RawId {
assert_eq!(0, epoch >> EPOCH_BITS);
assert_eq!(0, (index as IdType) >> INDEX_BITS);
let v = index as IdType
| ((epoch as IdType) << INDEX_BITS)
| ((backend as IdType) << BACKEND_SHIFT);
Self(NonZeroId::new(v).unwrap())
}
/// Unzip a raw identifier into its components.
pub fn unzip(self) -> (Index, Epoch) {
(self.0.get() as Index, (self.0.get() >> 32) as Epoch)
#[allow(trivial_numeric_casts)]
pub fn unzip(self) -> (Index, Epoch, Backend) {
(
(self.0.get() as ZippedIndex) as Index,
(((self.0.get() >> INDEX_BITS) as ZippedIndex) & (EPOCH_MASK as ZippedIndex)) as Index,
self.backend(),
)
}
pub fn backend(self) -> Backend {
match self.0.get() >> (BACKEND_SHIFT) as u8 {
0 => Backend::Empty,
1 => Backend::Vulkan,
2 => Backend::Metal,
3 => Backend::Dx12,
4 => Backend::Gl,
_ => unreachable!(),
}
}
}
@ -91,20 +116,20 @@ pub struct Id<T: Marker>(RawId, PhantomData<T>);
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
enum SerialId {
// The only variant forces RON to not ignore "Id"
Id(Index, Epoch),
Id(Index, Epoch, Backend),
}
impl From<RawId> for SerialId {
fn from(id: RawId) -> Self {
let (index, epoch) = id.unzip();
Self::Id(index, epoch)
let (index, epoch, backend) = id.unzip();
Self::Id(index, epoch, backend)
}
}
impl From<SerialId> for RawId {
fn from(id: SerialId) -> Self {
match id {
SerialId::Id(index, epoch) => RawId::zip(index, epoch),
SerialId::Id(index, epoch, backend) => RawId::zip(index, epoch, backend),
}
}
}
@ -125,13 +150,29 @@ where
self.0
}
#[allow(dead_code)]
pub(crate) fn dummy(index: u32) -> Self {
Id::zip(index, 1, Backend::Empty)
}
#[allow(dead_code)]
pub(crate) fn is_valid(&self) -> bool {
self.backend() != Backend::Empty
}
/// Get the backend this identifier corresponds to.
#[inline]
pub fn zip(index: Index, epoch: Epoch) -> Self {
Id(RawId::zip(index, epoch), PhantomData)
pub fn backend(self) -> Backend {
self.0.backend()
}
#[inline]
pub fn unzip(self) -> (Index, Epoch) {
pub fn zip(index: Index, epoch: Epoch, backend: Backend) -> Self {
Id(RawId::zip(index, epoch, backend), PhantomData)
}
#[inline]
pub fn unzip(self) -> (Index, Epoch, Backend) {
self.0.unzip()
}
}
@ -153,8 +194,16 @@ where
T: Marker,
{
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let (index, epoch) = self.unzip();
write!(formatter, "Id({index},{epoch})")?;
let (index, epoch, backend) = self.unzip();
let backend = match backend {
Backend::Empty => "_",
Backend::Vulkan => "vk",
Backend::Metal => "mtl",
Backend::Dx12 => "d3d12",
Backend::Gl => "gl",
Backend::BrowserWebGpu => "webgpu",
};
write!(formatter, "Id({index},{epoch},{backend})")?;
Ok(())
}
}
@ -277,16 +326,43 @@ impl CommandBufferId {
}
}
#[test]
fn test_id_backend() {
for &b in &[
Backend::Empty,
Backend::Vulkan,
Backend::Metal,
Backend::Dx12,
Backend::Gl,
] {
let id = Id::<()>::zip(1, 0, b);
let (_id, _epoch, backend) = id.unzip();
assert_eq!(id.backend(), b);
assert_eq!(backend, b);
}
}
#[test]
fn test_id() {
let indexes = [0, Index::MAX / 2 - 1, Index::MAX / 2 + 1, Index::MAX];
let epochs = [1, Epoch::MAX / 2 - 1, Epoch::MAX / 2 + 1, Epoch::MAX];
let last_index = ((1u64 << INDEX_BITS) - 1) as Index;
let indexes = [1, last_index / 2 - 1, last_index / 2 + 1, last_index];
let epochs = [1, EPOCH_MASK / 2 - 1, EPOCH_MASK / 2 + 1, EPOCH_MASK];
let backends = [
Backend::Empty,
Backend::Vulkan,
Backend::Metal,
Backend::Dx12,
Backend::Gl,
];
for &i in &indexes {
for &e in &epochs {
let id = Id::<()>::zip(i, e);
let (index, epoch) = id.unzip();
assert_eq!(index, i);
assert_eq!(epoch, e);
for &b in &backends {
let id = Id::<()>::zip(i, e, b);
let (index, epoch, backend) = id.unzip();
assert_eq!(index, i);
assert_eq!(epoch, e);
assert_eq!(backend, b);
}
}
}
}

22
third_party/rust/wgpu-core/src/identity.rs поставляемый
Просмотреть файл

@ -1,3 +1,5 @@
use wgt::Backend;
use crate::{
id::{Id, Marker},
lock::{rank, Mutex},
@ -50,7 +52,7 @@ impl IdentityValues {
///
/// The backend is incorporated into the id, so that ids allocated with
/// different `backend` values are always distinct.
pub fn alloc<T: Marker>(&mut self) -> Id<T> {
pub fn alloc<T: Marker>(&mut self, backend: Backend) -> Id<T> {
assert!(
self.id_source != IdSource::External,
"Mix of internally allocated and externally provided IDs"
@ -59,12 +61,12 @@ impl IdentityValues {
self.count += 1;
match self.free.pop() {
Some((index, epoch)) => Id::zip(index, epoch + 1),
Some((index, epoch)) => Id::zip(index, epoch + 1, backend),
None => {
let index = self.next_index;
self.next_index += 1;
let epoch = 1;
Id::zip(index, epoch)
Id::zip(index, epoch, backend)
}
}
}
@ -83,7 +85,7 @@ impl IdentityValues {
/// Free `id`. It will never be returned from `alloc` again.
pub fn release<T: Marker>(&mut self, id: Id<T>) {
if let IdSource::Allocated = self.id_source {
let (index, epoch) = id.unzip();
let (index, epoch, _backend) = id.unzip();
self.free.push((index, epoch));
}
self.count -= 1;
@ -101,8 +103,8 @@ pub struct IdentityManager<T: Marker> {
}
impl<T: Marker> IdentityManager<T> {
pub fn process(&self) -> Id<T> {
self.values.lock().alloc()
pub fn process(&self, backend: Backend) -> Id<T> {
self.values.lock().alloc(backend)
}
pub fn mark_as_used(&self, id: Id<T>) -> Id<T> {
self.values.lock().mark_as_used(id)
@ -133,10 +135,10 @@ impl<T: Marker> IdentityManager<T> {
fn test_epoch_end_of_life() {
use crate::id;
let man = IdentityManager::<id::markers::Buffer>::new();
let id1 = man.process();
assert_eq!(id1.unzip(), (0, 1));
let id1 = man.process(Backend::Empty);
assert_eq!(id1.unzip(), (0, 1, Backend::Empty));
man.free(id1);
let id2 = man.process();
let id2 = man.process(Backend::Empty);
// confirm that the epoch 1 is no longer re-used
assert_eq!(id2.unzip(), (0, 2));
assert_eq!(id2.unzip(), (0, 2, Backend::Empty));
}

288
third_party/rust/wgpu-core/src/instance.rs поставляемый
Просмотреть файл

@ -1,12 +1,13 @@
use std::sync::Arc;
use std::{borrow::Cow, collections::HashMap};
use crate::hub::Hub;
use crate::{
api_log,
device::{queue::Queue, resource::Device, DeviceDescriptor, DeviceError},
global::Global,
hal_api::HalApi,
id::{markers, AdapterId, DeviceId, QueueId, SurfaceId},
id::{markers, AdapterId, DeviceId, Id, Marker, QueueId, SurfaceId},
lock::{rank, Mutex},
present::Presentation,
resource::ResourceType,
@ -367,6 +368,26 @@ pub enum RequestDeviceError {
UnsupportedFeature(wgt::Features),
}
pub enum AdapterInputs<'a, M: Marker> {
IdSet(&'a [Id<M>]),
Mask(Backends, fn(Backend) -> Option<Id<M>>),
}
impl<M: Marker> AdapterInputs<'_, M> {
fn find(&self, b: Backend) -> Option<Option<Id<M>>> {
match *self {
Self::IdSet(ids) => Some(Some(ids.iter().find(|id| id.backend() == b).copied()?)),
Self::Mask(bits, ref fun) => {
if bits.contains(b.into()) {
Some(fun(b))
} else {
None
}
}
}
}
}
#[derive(Clone, Debug, Error)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[non_exhaustive]
@ -446,7 +467,7 @@ impl Global {
let id = self
.surfaces
.prepare(id_in) // No specific backend for Surface, since it's not specific.
.prepare(Backend::Empty, id_in) // No specific backend for Surface, since it's not specific.
.assign(Arc::new(surface));
Ok(id)
}
@ -490,7 +511,10 @@ impl Global {
surface_per_backend: std::iter::once((Backend::Metal, raw_surface)).collect(),
};
let id = self.surfaces.prepare(id_in).assign(Arc::new(surface));
let id = self
.surfaces
.prepare(Backend::Metal, id_in)
.assign(Arc::new(surface));
Ok(id)
}
@ -512,7 +536,10 @@ impl Global {
surface_per_backend: std::iter::once((Backend::Dx12, surface)).collect(),
};
let id = self.surfaces.prepare(id_in).assign(Arc::new(surface));
let id = self
.surfaces
.prepare(Backend::Dx12, id_in)
.assign(Arc::new(surface));
Ok(id)
}
@ -580,81 +607,178 @@ impl Global {
drop(surface)
}
pub fn enumerate_adapters(&self, backends: Backends) -> Vec<AdapterId> {
pub fn enumerate_adapters(&self, inputs: AdapterInputs<markers::Adapter>) -> Vec<AdapterId> {
profiling::scope!("Instance::enumerate_adapters");
api_log!("Instance::enumerate_adapters");
let mut adapters = Vec::new();
for (_, instance) in self
.instance
.instance_per_backend
.iter()
.filter(|(backend, _)| backends.contains(Backends::from(*backend)))
{
fn enumerate(
hub: &Hub,
backend: Backend,
instance: &dyn hal::DynInstance,
inputs: &AdapterInputs<markers::Adapter>,
list: &mut Vec<AdapterId>,
) {
let Some(id_backend) = inputs.find(backend) else {
return;
};
profiling::scope!("enumerating", &*format!("{:?}", backend));
let hal_adapters = unsafe { instance.enumerate_adapters(None) };
for raw in hal_adapters {
let adapter = Adapter::new(raw);
log::info!("Adapter {:?}", adapter.raw.info);
let id = self.hub.adapters.prepare(None).assign(Arc::new(adapter));
adapters.push(id);
let id = hub
.adapters
.prepare(backend, id_backend)
.assign(Arc::new(adapter));
list.push(id);
}
}
let mut adapters = Vec::new();
for (backend, instance) in &self.instance.instance_per_backend {
enumerate(
&self.hub,
*backend,
instance.as_ref(),
&inputs,
&mut adapters,
);
}
adapters
}
fn select(
&self,
backend: Backend,
selected: &mut usize,
new_id: Option<AdapterId>,
mut list: Vec<hal::DynExposedAdapter>,
) -> Option<AdapterId> {
match selected.checked_sub(list.len()) {
Some(left) => {
*selected = left;
None
}
None => {
let adapter = Adapter::new(list.swap_remove(*selected));
log::info!("Adapter {:?}", adapter.raw.info);
let id = self
.hub
.adapters
.prepare(backend, new_id)
.assign(Arc::new(adapter));
Some(id)
}
}
}
pub fn request_adapter(
&self,
desc: &RequestAdapterOptions,
backends: Backends,
id_in: Option<AdapterId>,
inputs: AdapterInputs<markers::Adapter>,
) -> Result<AdapterId, RequestAdapterError> {
profiling::scope!("Instance::request_adapter");
api_log!("Instance::request_adapter");
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::DynExposedAdapter>) {
let id = inputs.find(backend);
match (id, instance.raw(backend)) {
(Some(id), Some(inst)) => {
let compatible_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());
}
device_types.extend(adapters.iter().map(|ad| ad.info.device_type));
(id, adapters)
}
_ => (None, Vec::new()),
}
}
let compatible_surface = desc.compatible_surface.map(|id| self.surfaces.get(id));
let compatible_surface = compatible_surface.as_ref().map(|surface| surface.as_ref());
let mut adapters = Vec::new();
let mut device_types = Vec::new();
for (backend, instance) in self
.instance
.instance_per_backend
.iter()
.filter(|(backend, _)| backends.contains(Backends::from(*backend)))
{
let compatible_hal_surface =
compatible_surface.and_then(|surface| surface.raw(*backend));
let mut backend_adapters =
unsafe { instance.enumerate_adapters(compatible_hal_surface) };
if desc.force_fallback_adapter {
backend_adapters.retain(|exposed| exposed.info.device_type == wgt::DeviceType::Cpu);
}
if let Some(surface) = compatible_surface {
backend_adapters
.retain(|exposed| surface.get_capabilities_with_raw(exposed).is_ok());
}
adapters.extend(backend_adapters);
#[cfg(vulkan)]
let (id_vulkan, adapters_vk) = gather(
Backend::Vulkan,
&self.instance,
&inputs,
compatible_surface,
desc.force_fallback_adapter,
&mut device_types,
);
#[cfg(metal)]
let (id_metal, adapters_metal) = gather(
Backend::Metal,
&self.instance,
&inputs,
compatible_surface,
desc.force_fallback_adapter,
&mut device_types,
);
#[cfg(dx12)]
let (id_dx12, adapters_dx12) = gather(
Backend::Dx12,
&self.instance,
&inputs,
compatible_surface,
desc.force_fallback_adapter,
&mut device_types,
);
#[cfg(gles)]
let (id_gl, adapters_gl) = gather(
Backend::Gl,
&self.instance,
&inputs,
compatible_surface,
desc.force_fallback_adapter,
&mut device_types,
);
if device_types.is_empty() {
return Err(RequestAdapterError::NotFound);
}
match desc.power_preference {
PowerPreference::LowPower => {
sort(&mut adapters, true);
}
PowerPreference::HighPerformance => {
sort(&mut adapters, false);
}
PowerPreference::None => {}
};
let (mut integrated, mut discrete, mut virt, mut cpu, mut other) =
(None, None, None, None, None);
fn sort(adapters: &mut [hal::DynExposedAdapter], prefer_integrated_gpu: bool) {
adapters.sort_by(|a, b| {
get_order(a.info.device_type, prefer_integrated_gpu)
.cmp(&get_order(b.info.device_type, prefer_integrated_gpu))
});
for (i, ty) in device_types.into_iter().enumerate() {
match ty {
wgt::DeviceType::IntegratedGpu => {
integrated = integrated.or(Some(i));
}
wgt::DeviceType::DiscreteGpu => {
discrete = discrete.or(Some(i));
}
wgt::DeviceType::VirtualGpu => {
virt = virt.or(Some(i));
}
wgt::DeviceType::Cpu => {
cpu = cpu.or(Some(i));
}
wgt::DeviceType::Other => {
other = other.or(Some(i));
}
}
}
fn get_order(device_type: wgt::DeviceType, prefer_integrated_gpu: bool) -> u8 {
let preferred_gpu = match desc.power_preference {
// Since devices of type "Other" might really be "Unknown" and come
// from APIs like OpenGL that don't specify device type, Prefer more
// Specific types over Other.
@ -662,28 +786,42 @@ impl Global {
// This means that backends which do provide accurate device types
// will be preferred if their device type indicates an actual
// hardware GPU (integrated or discrete).
match device_type {
wgt::DeviceType::DiscreteGpu if prefer_integrated_gpu => 2,
wgt::DeviceType::IntegratedGpu if prefer_integrated_gpu => 1,
wgt::DeviceType::DiscreteGpu => 1,
wgt::DeviceType::IntegratedGpu => 2,
wgt::DeviceType::Other => 3,
wgt::DeviceType::VirtualGpu => 4,
wgt::DeviceType::Cpu => 5,
PowerPreference::LowPower => integrated.or(discrete).or(other).or(virt).or(cpu),
PowerPreference::HighPerformance => discrete.or(integrated).or(other).or(virt).or(cpu),
PowerPreference::None => {
let option_min = |a: Option<usize>, b: Option<usize>| {
if let (Some(a), Some(b)) = (a, b) {
Some(a.min(b))
} else {
a.or(b)
}
};
// Pick the lowest id of these types
option_min(option_min(discrete, integrated), other)
}
}
};
if let Some(adapter) = adapters.into_iter().next() {
log::info!("Adapter {:?}", adapter.info);
let id = self
.hub
.adapters
.prepare(id_in)
.assign(Arc::new(Adapter::new(adapter)));
Ok(id)
} else {
Err(RequestAdapterError::NotFound)
let mut selected = preferred_gpu.unwrap_or(0);
#[cfg(vulkan)]
if let Some(id) = self.select(Backend::Vulkan, &mut selected, id_vulkan, adapters_vk) {
return Ok(id);
}
#[cfg(metal)]
if let Some(id) = self.select(Backend::Metal, &mut selected, id_metal, adapters_metal) {
return Ok(id);
}
#[cfg(dx12)]
if let Some(id) = self.select(Backend::Dx12, &mut selected, id_dx12, adapters_dx12) {
return Ok(id);
}
#[cfg(gles)]
if let Some(id) = self.select(Backend::Gl, &mut selected, id_gl, adapters_gl) {
return Ok(id);
}
let _ = selected;
log::warn!("Some adapters are present, but enumerating them failed!");
Err(RequestAdapterError::NotFound)
}
/// # Safety
@ -696,7 +834,7 @@ impl Global {
) -> AdapterId {
profiling::scope!("Instance::create_adapter_from_hal");
let fid = self.hub.adapters.prepare(input);
let fid = self.hub.adapters.prepare(hal_adapter.backend(), input);
let id = fid.assign(Arc::new(Adapter::new(hal_adapter)));
resource_log!("Created Adapter {:?}", id);
@ -763,8 +901,9 @@ impl Global {
profiling::scope!("Adapter::request_device");
api_log!("Adapter::request_device");
let device_fid = self.hub.devices.prepare(device_id_in);
let queue_fid = self.hub.queues.prepare(queue_id_in);
let backend = adapter_id.backend();
let device_fid = self.hub.devices.prepare(backend, device_id_in);
let queue_fid = self.hub.queues.prepare(backend, queue_id_in);
let adapter = self.hub.adapters.get(adapter_id);
let (device, queue) =
@ -794,8 +933,9 @@ impl Global {
) -> Result<(DeviceId, QueueId), RequestDeviceError> {
profiling::scope!("Global::create_device_from_hal");
let devices_fid = self.hub.devices.prepare(device_id_in);
let queues_fid = self.hub.queues.prepare(queue_id_in);
let backend = adapter_id.backend();
let devices_fid = self.hub.devices.prepare(backend, device_id_in);
let queues_fid = self.hub.queues.prepare(backend, queue_id_in);
let adapter = self.hub.adapters.get(adapter_id);
let (device, queue) = adapter.create_device_and_queue_from_hal(

2
third_party/rust/wgpu-core/src/present.rs поставляемый
Просмотреть файл

@ -131,7 +131,7 @@ impl Global {
return Err(SurfaceError::NotConfigured);
};
let fid = hub.textures.prepare(texture_id_in);
let fid = hub.textures.prepare(device.backend(), texture_id_in);
#[cfg(feature = "trace")]
if let Some(ref mut trace) = *device.trace.lock() {

10
third_party/rust/wgpu-core/src/registry.rs поставляемый
Просмотреть файл

@ -70,14 +70,18 @@ impl<T: StorageItem> FutureId<'_, T> {
}
impl<T: StorageItem> Registry<T> {
pub(crate) fn prepare(&self, id_in: Option<Id<T::Marker>>) -> FutureId<T> {
pub(crate) fn prepare(
&self,
backend: wgt::Backend,
id_in: Option<Id<T::Marker>>,
) -> FutureId<T> {
FutureId {
id: match id_in {
Some(id_in) => {
self.identity.mark_as_used(id_in);
id_in
}
None => self.identity.process(),
None => self.identity.process(backend),
},
data: &self.storage,
}
@ -150,7 +154,7 @@ mod tests {
s.spawn(|| {
for _ in 0..1000 {
let value = Arc::new(TestData);
let new_id = registry.prepare(None);
let new_id = registry.prepare(wgt::Backend::Empty, None);
let id = new_id.assign(value);
registry.remove(id);
}

12
third_party/rust/wgpu-core/src/storage.rs поставляемый
Просмотреть файл

@ -1,5 +1,7 @@
use std::sync::Arc;
use wgt::Backend;
use crate::id::{Id, Marker};
use crate::resource::ResourceType;
use crate::{Epoch, Index};
@ -73,7 +75,7 @@ where
T: StorageItem,
{
pub(crate) fn insert(&mut self, id: Id<T::Marker>, value: T) {
let (index, epoch) = id.unzip();
let (index, epoch, _) = id.unzip();
let index = index as usize;
if index >= self.map.len() {
self.map.resize_with(index + 1, || Element::Vacant);
@ -92,7 +94,7 @@ where
}
pub(crate) fn remove(&mut self, id: Id<T::Marker>) -> T {
let (index, epoch) = id.unzip();
let (index, epoch, _) = id.unzip();
match std::mem::replace(&mut self.map[index as usize], Element::Vacant) {
Element::Occupied(value, storage_epoch) => {
assert_eq!(epoch, storage_epoch);
@ -102,13 +104,13 @@ where
}
}
pub(crate) fn iter(&self) -> impl Iterator<Item = (Id<T::Marker>, &T)> {
pub(crate) fn iter(&self, backend: Backend) -> impl Iterator<Item = (Id<T::Marker>, &T)> {
self.map
.iter()
.enumerate()
.filter_map(move |(index, x)| match *x {
Element::Occupied(ref value, storage_epoch) => {
Some((Id::zip(index as Index, storage_epoch), value))
Some((Id::zip(index as Index, storage_epoch, backend), value))
}
_ => None,
})
@ -126,7 +128,7 @@ where
/// Get an owned reference to an item.
/// Panics if there is an epoch mismatch, the entry is empty or in error.
pub(crate) fn get(&self, id: Id<T::Marker>) -> T {
let (index, epoch) = id.unzip();
let (index, epoch, _) = id.unzip();
let (result, storage_epoch) = match self.map.get(index as usize) {
Some(&Element::Occupied(ref v, epoch)) => (v.clone(), epoch),
None | Some(&Element::Vacant) => panic!("{}[{:?}] does not exist", self.kind, id),

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -138,7 +138,7 @@ pub fn create_factory(
// The `DXGI_CREATE_FACTORY_DEBUG` flag is only allowed to be passed to
// `CreateDXGIFactory2` if the debug interface is actually available. So
// we check for whether it exists first.
if let Ok(Some(_)) = lib_dxgi.debug_interface1() {
if lib_dxgi.debug_interface1().is_ok() {
factory_flags |= Dxgi::DXGI_CREATE_FACTORY_DEBUG;
}

Просмотреть файл

@ -34,7 +34,7 @@ impl crate::Instance for super::Instance {
.intersects(wgt::InstanceFlags::VALIDATION | wgt::InstanceFlags::GPU_BASED_VALIDATION)
{
// Enable debug layer
if let Ok(Some(debug_controller)) = lib_main.debug_interface() {
if let Ok(debug_controller) = lib_main.debug_interface() {
if desc.flags.intersects(wgt::InstanceFlags::VALIDATION) {
unsafe { debug_controller.EnableDebugLayer() }
}

34
third_party/rust/wgpu-hal/src/dx12/mod.rs поставляемый
Просмотреть файл

@ -190,7 +190,7 @@ impl D3D12Lib {
blob.ok_or(crate::DeviceError::Unexpected)
}
fn debug_interface(&self) -> Result<Option<Direct3D12::ID3D12Debug>, crate::DeviceError> {
fn debug_interface(&self) -> Result<Direct3D12::ID3D12Debug, crate::DeviceError> {
// Calls windows::Win32::Graphics::Direct3D12::D3D12GetDebugInterface on d3d12.dll
type Fun = extern "system" fn(
riid: *const windows_core::GUID,
@ -200,18 +200,11 @@ impl D3D12Lib {
let mut result__ = None;
let res = (func)(&Direct3D12::ID3D12Debug::IID, <*mut _>::cast(&mut result__)).ok();
(func)(&Direct3D12::ID3D12Debug::IID, <*mut _>::cast(&mut result__))
.ok()
.into_device_result("GetDebugInterface")?;
if let Err(ref err) = res {
match err.code() {
Dxgi::DXGI_ERROR_SDK_COMPONENT_MISSING => return Ok(None),
_ => {}
}
}
res.into_device_result("GetDebugInterface")?;
result__.ok_or(crate::DeviceError::Unexpected).map(Some)
result__.ok_or(crate::DeviceError::Unexpected)
}
}
@ -226,7 +219,7 @@ impl DxgiLib {
}
/// Will error with crate::DeviceError::Unexpected if DXGI 1.3 is not available.
pub fn debug_interface1(&self) -> Result<Option<Dxgi::IDXGIInfoQueue>, crate::DeviceError> {
pub fn debug_interface1(&self) -> Result<Dxgi::IDXGIInfoQueue, crate::DeviceError> {
// Calls windows::Win32::Graphics::Dxgi::DXGIGetDebugInterface1 on dxgi.dll
type Fun = extern "system" fn(
flags: u32,
@ -237,18 +230,11 @@ impl DxgiLib {
let mut result__ = None;
let res = (func)(0, &Dxgi::IDXGIInfoQueue::IID, <*mut _>::cast(&mut result__)).ok();
(func)(0, &Dxgi::IDXGIInfoQueue::IID, <*mut _>::cast(&mut result__))
.ok()
.into_device_result("debug_interface1")?;
if let Err(ref err) = res {
match err.code() {
Dxgi::DXGI_ERROR_SDK_COMPONENT_MISSING => return Ok(None),
_ => {}
}
}
res.into_device_result("debug_interface1")?;
result__.ok_or(crate::DeviceError::Unexpected).map(Some)
result__.ok_or(crate::DeviceError::Unexpected)
}
/// Will error with crate::DeviceError::Unexpected if DXGI 1.4 is not available.