зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 128de7e126a3 (bug 1918739) for causing wgpu_bindings related bustages CLOSED TREE
This commit is contained in:
Родитель
3ac3a31b8f
Коммит
12a6115875
|
@ -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"]
|
||||
|
|
|
@ -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:?}");
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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() }
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче