зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1852485 - Present WebGPU by using DX11 texture in swap chain with readback on Windows r=webgpu-reviewers,nical
The change is preparation for Bug 1843891. Current gecko uses a internal texture for SwapChain's texture. This bug changes as to use external dx11 texture for WebGPU dx12 backend on Windows. WebGPUParent allocates dx11 texture for SwapChain's texture of dx12 backend WebGPU. wgpu uses the dx11 texture as ID3D12Resource. The readback for presenting to WebRender still exists. The change handles only RBGA format. Differential Revision: https://phabricator.services.mozilla.com/D187870
This commit is contained in:
Родитель
8506bd8355
Коммит
a8dfa5bebe
|
@ -6391,6 +6391,7 @@ name = "wgpu_bindings"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"d3d12",
|
||||
"log",
|
||||
"nsstring",
|
||||
"parking_lot",
|
||||
|
@ -6399,6 +6400,7 @@ dependencies = [
|
|||
"wgpu-core",
|
||||
"wgpu-hal",
|
||||
"wgpu-types",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -117,7 +117,12 @@ void CanvasContext::Configure(const dom::GPUCanvasConfiguration& aConfig) {
|
|||
|
||||
mConfig.reset(new dom::GPUCanvasConfiguration(aConfig));
|
||||
mRemoteTextureOwnerId = Some(layers::RemoteTextureOwnerId::GetNext());
|
||||
mUseExternalTextureInSwapChain =
|
||||
wgpu_client_use_external_texture_in_swapChain(
|
||||
aConfig.mDevice->mId,
|
||||
WebGPUChild::ConvertTextureFormat(aConfig.mFormat));
|
||||
mTexture = aConfig.mDevice->InitSwapChain(aConfig, *mRemoteTextureOwnerId,
|
||||
mUseExternalTextureInSwapChain,
|
||||
mGfxFormat, mCanvasSize);
|
||||
if (!mTexture) {
|
||||
Unconfigure();
|
||||
|
|
|
@ -100,6 +100,7 @@ class CanvasContext final : public nsICanvasRenderingContextInternal,
|
|||
|
||||
Maybe<layers::RemoteTextureId> mLastRemoteTextureId;
|
||||
Maybe<layers::RemoteTextureOwnerId> mRemoteTextureOwnerId;
|
||||
bool mUseExternalTextureInSwapChain = false;
|
||||
};
|
||||
|
||||
} // namespace webgpu
|
||||
|
|
|
@ -121,9 +121,15 @@ already_AddRefed<Buffer> Device::CreateBuffer(
|
|||
|
||||
already_AddRefed<Texture> Device::CreateTexture(
|
||||
const dom::GPUTextureDescriptor& aDesc) {
|
||||
return CreateTexture(aDesc, /* aOwnerId */ Nothing());
|
||||
}
|
||||
|
||||
already_AddRefed<Texture> Device::CreateTexture(
|
||||
const dom::GPUTextureDescriptor& aDesc,
|
||||
Maybe<layers::RemoteTextureOwnerId> aOwnerId) {
|
||||
RawId id = 0;
|
||||
if (mBridge->CanSend()) {
|
||||
id = mBridge->DeviceCreateTexture(mId, aDesc);
|
||||
id = mBridge->DeviceCreateTexture(mId, aDesc, aOwnerId);
|
||||
}
|
||||
RefPtr<Texture> texture = new Texture(this, id, aDesc);
|
||||
return texture.forget();
|
||||
|
@ -294,7 +300,8 @@ already_AddRefed<dom::Promise> Device::CreateRenderPipelineAsync(
|
|||
|
||||
already_AddRefed<Texture> Device::InitSwapChain(
|
||||
const dom::GPUCanvasConfiguration& aDesc,
|
||||
const layers::RemoteTextureOwnerId aOwnerId, gfx::SurfaceFormat aFormat,
|
||||
const layers::RemoteTextureOwnerId aOwnerId,
|
||||
bool aUseExternalTextureInSwapChain, gfx::SurfaceFormat aFormat,
|
||||
gfx::IntSize aCanvasSize) {
|
||||
if (!mBridge->CanSend()) {
|
||||
return nullptr;
|
||||
|
@ -303,7 +310,8 @@ already_AddRefed<Texture> Device::InitSwapChain(
|
|||
const layers::RGBDescriptor rgbDesc(aCanvasSize, aFormat);
|
||||
// buffer count doesn't matter much, will be created on demand
|
||||
const size_t maxBufferCount = 10;
|
||||
mBridge->DeviceCreateSwapChain(mId, rgbDesc, maxBufferCount, aOwnerId);
|
||||
mBridge->DeviceCreateSwapChain(mId, rgbDesc, maxBufferCount, aOwnerId,
|
||||
aUseExternalTextureInSwapChain);
|
||||
|
||||
dom::GPUTextureDescriptor desc;
|
||||
desc.mDimension = dom::GPUTextureDimension::_2d;
|
||||
|
@ -318,7 +326,7 @@ already_AddRefed<Texture> Device::InitSwapChain(
|
|||
desc.mViewFormats = aDesc.mViewFormats;
|
||||
// TODO: `mColorSpace`: <https://bugzilla.mozilla.org/show_bug.cgi?id=1846608>
|
||||
// TODO: `mAlphaMode`: <https://bugzilla.mozilla.org/show_bug.cgi?id=1846605>
|
||||
return CreateTexture(desc);
|
||||
return CreateTexture(desc, Some(aOwnerId));
|
||||
}
|
||||
|
||||
bool Device::CheckNewWarning(const nsACString& aMessage) {
|
||||
|
|
|
@ -94,7 +94,8 @@ class Device final : public DOMEventTargetHelper, public SupportsWeakPtr {
|
|||
RefPtr<WebGPUChild> GetBridge();
|
||||
already_AddRefed<Texture> InitSwapChain(
|
||||
const dom::GPUCanvasConfiguration& aDesc,
|
||||
const layers::RemoteTextureOwnerId aOwnerId, gfx::SurfaceFormat aFormat,
|
||||
const layers::RemoteTextureOwnerId aOwnerId,
|
||||
bool aUseExternalTextureInSwapChain, gfx::SurfaceFormat aFormat,
|
||||
gfx::IntSize aCanvasSize);
|
||||
bool CheckNewWarning(const nsACString& aMessage);
|
||||
|
||||
|
@ -130,6 +131,9 @@ class Device final : public DOMEventTargetHelper, public SupportsWeakPtr {
|
|||
|
||||
already_AddRefed<Texture> CreateTexture(
|
||||
const dom::GPUTextureDescriptor& aDesc);
|
||||
already_AddRefed<Texture> CreateTexture(
|
||||
const dom::GPUTextureDescriptor& aDesc,
|
||||
Maybe<layers::RemoteTextureOwnerId> aOwnerId);
|
||||
already_AddRefed<Sampler> CreateSampler(
|
||||
const dom::GPUSamplerDescriptor& aDesc);
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ExternalTexture.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
# include "mozilla/webgpu/ExternalTextureD3D11.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla::webgpu {
|
||||
|
||||
// static
|
||||
UniquePtr<ExternalTexture> ExternalTexture::Create(
|
||||
const uint32_t aWidth, const uint32_t aHeight,
|
||||
const struct ffi::WGPUTextureFormat aFormat) {
|
||||
UniquePtr<ExternalTexture> texture;
|
||||
#ifdef XP_WIN
|
||||
texture = ExternalTextureD3D11::Create(aWidth, aHeight, aFormat);
|
||||
#endif
|
||||
return texture;
|
||||
}
|
||||
|
||||
ExternalTexture::ExternalTexture(const uint32_t aWidth, const uint32_t aHeight,
|
||||
const struct ffi::WGPUTextureFormat aFormat)
|
||||
: mWidth(aWidth), mHeight(aHeight), mFormat(aFormat) {}
|
||||
|
||||
ExternalTexture::~ExternalTexture() {}
|
||||
|
||||
} // namespace mozilla::webgpu
|
|
@ -0,0 +1,43 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef ExternalTexture_H_
|
||||
#define ExternalTexture_H_
|
||||
|
||||
#include "mozilla/gfx/Point.h"
|
||||
#include "mozilla/layers/LayersSurfaces.h"
|
||||
#include "mozilla/webgpu/ffi/wgpu.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace webgpu {
|
||||
|
||||
// A texture that can be used by the WebGPU implementation but is created and
|
||||
// owned by Gecko
|
||||
class ExternalTexture {
|
||||
public:
|
||||
static UniquePtr<ExternalTexture> Create(
|
||||
const uint32_t aWidth, const uint32_t aHeight,
|
||||
const struct ffi::WGPUTextureFormat aFormat);
|
||||
|
||||
ExternalTexture(const uint32_t aWidth, const uint32_t aHeight,
|
||||
const struct ffi::WGPUTextureFormat aFormat);
|
||||
virtual ~ExternalTexture();
|
||||
|
||||
virtual void* GetExternalTextureHandle() { return nullptr; }
|
||||
|
||||
virtual Maybe<layers::SurfaceDescriptor> ToSurfaceDescriptor() = 0;
|
||||
|
||||
gfx::IntSize GetSize() { return gfx::IntSize(mWidth, mHeight); }
|
||||
|
||||
const uint32_t mWidth;
|
||||
const uint32_t mHeight;
|
||||
const struct ffi::WGPUTextureFormat mFormat;
|
||||
};
|
||||
|
||||
} // namespace webgpu
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GPU_ExternalTexture_H_
|
|
@ -0,0 +1,82 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ExternalTextureD3D11.h"
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
#include "mozilla/gfx/DeviceManagerDx.h"
|
||||
|
||||
namespace mozilla::webgpu {
|
||||
|
||||
// static
|
||||
UniquePtr<ExternalTextureD3D11> ExternalTextureD3D11::Create(
|
||||
const uint32_t aWidth, const uint32_t aHeight,
|
||||
const struct ffi::WGPUTextureFormat aFormat) {
|
||||
const RefPtr<ID3D11Device> d3d11Device =
|
||||
gfx::DeviceManagerDx::Get()->GetCompositorDevice();
|
||||
if (!d3d11Device) {
|
||||
gfxCriticalNoteOnce << "CompositorDevice does not exist";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aFormat.tag != ffi::WGPUTextureFormat_Bgra8Unorm) {
|
||||
gfxCriticalNoteOnce << "Non supported format: " << aFormat.tag;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CD3D11_TEXTURE2D_DESC desc(
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM, aWidth, aHeight, 1, 1,
|
||||
D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
|
||||
|
||||
desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
|
||||
|
||||
RefPtr<ID3D11Texture2D> texture;
|
||||
HRESULT hr =
|
||||
d3d11Device->CreateTexture2D(&desc, nullptr, getter_AddRefs(texture));
|
||||
if (FAILED(hr)) {
|
||||
gfxCriticalNoteOnce << "CreateTexture2D failed: " << gfx::hexa(hr);
|
||||
return nullptr;
|
||||
}
|
||||
return MakeUnique<ExternalTextureD3D11>(aWidth, aHeight, aFormat, texture);
|
||||
}
|
||||
|
||||
ExternalTextureD3D11::ExternalTextureD3D11(
|
||||
const uint32_t aWidth, const uint32_t aHeight,
|
||||
const struct ffi::WGPUTextureFormat aFormat,
|
||||
RefPtr<ID3D11Texture2D> aTexture)
|
||||
: ExternalTexture(aWidth, aHeight, aFormat), mTexture(aTexture) {
|
||||
MOZ_ASSERT(mTexture);
|
||||
}
|
||||
|
||||
ExternalTextureD3D11::~ExternalTextureD3D11() {}
|
||||
|
||||
void* ExternalTextureD3D11::GetExternalTextureHandle() {
|
||||
RefPtr<IDXGIResource> resource;
|
||||
mTexture->QueryInterface((IDXGIResource**)getter_AddRefs(resource));
|
||||
if (!resource) {
|
||||
gfxCriticalNoteOnce << "Failed to get IDXGIResource";
|
||||
return 0;
|
||||
}
|
||||
|
||||
HANDLE sharedHandle;
|
||||
HRESULT hr = resource->GetSharedHandle(&sharedHandle);
|
||||
if (FAILED(hr)) {
|
||||
gfxCriticalNoteOnce << "GetSharedHandle failed: " << gfx::hexa(hr);
|
||||
return 0;
|
||||
}
|
||||
return sharedHandle;
|
||||
}
|
||||
|
||||
Maybe<layers::SurfaceDescriptor> ExternalTextureD3D11::ToSurfaceDescriptor() {
|
||||
const auto format = gfx::SurfaceFormat::B8G8R8A8;
|
||||
return Some(layers::SurfaceDescriptorD3D10(
|
||||
(WindowsHandle)GetExternalTextureHandle(),
|
||||
/* gpuProcessTextureId */ Nothing(),
|
||||
/* arrayIndex */ 0, format, gfx::IntSize(mWidth, mHeight),
|
||||
gfx::ColorSpace2::SRGB, gfx::ColorRange::FULL, /* hasKeyedMutex */ true));
|
||||
}
|
||||
|
||||
} // namespace mozilla::webgpu
|
|
@ -0,0 +1,39 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GPU_ExternalTextureD3D11_H_
|
||||
#define GPU_ExternalTextureD3D11_H_
|
||||
|
||||
#include "mozilla/webgpu/ExternalTexture.h"
|
||||
|
||||
struct ID3D11Texture2D;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace webgpu {
|
||||
|
||||
class ExternalTextureD3D11 final : public ExternalTexture {
|
||||
public:
|
||||
static UniquePtr<ExternalTextureD3D11> Create(
|
||||
const uint32_t aWidth, const uint32_t aHeight,
|
||||
const struct ffi::WGPUTextureFormat aFormat);
|
||||
|
||||
ExternalTextureD3D11(const uint32_t aWidth, const uint32_t aHeight,
|
||||
const struct ffi::WGPUTextureFormat aFormat,
|
||||
RefPtr<ID3D11Texture2D> aTexture);
|
||||
virtual ~ExternalTextureD3D11();
|
||||
|
||||
void* GetExternalTextureHandle() override;
|
||||
|
||||
Maybe<layers::SurfaceDescriptor> ToSurfaceDescriptor() override;
|
||||
|
||||
protected:
|
||||
RefPtr<ID3D11Texture2D> mTexture;
|
||||
};
|
||||
|
||||
} // namespace webgpu
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // GPU_Texture_H_
|
|
@ -75,7 +75,7 @@ parent:
|
|||
async ComputePipelineDestroy(RawId selfId);
|
||||
async RenderPipelineDestroy(RawId selfId);
|
||||
async ImplicitLayoutDestroy(RawId implicitPlId, RawId[] implicitBglIds);
|
||||
async DeviceCreateSwapChain(RawId selfId, RawId queueId, RGBDescriptor desc, RawId[] bufferIds, RemoteTextureOwnerId ownerId);
|
||||
async DeviceCreateSwapChain(RawId selfId, RawId queueId, RGBDescriptor desc, RawId[] bufferIds, RemoteTextureOwnerId ownerId, bool useExternalTextureInSwapChain);
|
||||
async SwapChainPresent(RawId textureId, RawId commandEncoderId, RemoteTextureId remoteTextureId, RemoteTextureOwnerId remoteTextureOwnerId);
|
||||
async SwapChainDestroy(RemoteTextureOwnerId ownerId);
|
||||
|
||||
|
|
|
@ -302,8 +302,9 @@ RawId WebGPUChild::DeviceCreateBuffer(RawId aSelfId,
|
|||
return bufferId;
|
||||
}
|
||||
|
||||
RawId WebGPUChild::DeviceCreateTexture(RawId aSelfId,
|
||||
const dom::GPUTextureDescriptor& aDesc) {
|
||||
RawId WebGPUChild::DeviceCreateTexture(
|
||||
RawId aSelfId, const dom::GPUTextureDescriptor& aDesc,
|
||||
Maybe<layers::RemoteTextureOwnerId> aOwnerId) {
|
||||
ffi::WGPUTextureDescriptor desc = {};
|
||||
|
||||
webgpu::StringHelper label(aDesc.mLabel);
|
||||
|
@ -334,9 +335,14 @@ RawId WebGPUChild::DeviceCreateTexture(RawId aSelfId,
|
|||
}
|
||||
desc.view_formats = {viewFormats.Elements(), viewFormats.Length()};
|
||||
|
||||
Maybe<ffi::WGPUSwapChainId> ownerId;
|
||||
if (aOwnerId.isSome()) {
|
||||
ownerId = Some(ffi::WGPUSwapChainId{aOwnerId->mId});
|
||||
}
|
||||
|
||||
ByteBuf bb;
|
||||
RawId id = ffi::wgpu_client_create_texture(mClient.get(), aSelfId, &desc,
|
||||
ToFFI(&bb));
|
||||
RawId id = ffi::wgpu_client_create_texture(
|
||||
mClient.get(), aSelfId, &desc, ownerId.ptrOr(nullptr), ToFFI(&bb));
|
||||
if (!SendDeviceAction(aSelfId, std::move(bb))) {
|
||||
MOZ_CRASH("IPC failure");
|
||||
}
|
||||
|
@ -1124,14 +1130,16 @@ ipc::IPCResult WebGPUChild::RecvDropAction(const ipc::ByteBuf& aByteBuf) {
|
|||
|
||||
void WebGPUChild::DeviceCreateSwapChain(
|
||||
RawId aSelfId, const RGBDescriptor& aRgbDesc, size_t maxBufferCount,
|
||||
const layers::RemoteTextureOwnerId& aOwnerId) {
|
||||
const layers::RemoteTextureOwnerId& aOwnerId,
|
||||
bool aUseExternalTextureInSwapChain) {
|
||||
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(), aSelfId));
|
||||
}
|
||||
SendDeviceCreateSwapChain(aSelfId, queueId, aRgbDesc, bufferIds, aOwnerId);
|
||||
SendDeviceCreateSwapChain(aSelfId, queueId, aRgbDesc, bufferIds, aOwnerId,
|
||||
aUseExternalTextureInSwapChain);
|
||||
}
|
||||
|
||||
void WebGPUChild::QueueOnSubmittedWorkDone(
|
||||
|
|
|
@ -67,7 +67,8 @@ class WebGPUChild final : public PWebGPUChild, public SupportsWeakPtr {
|
|||
RawId DeviceCreateBuffer(RawId aSelfId, const dom::GPUBufferDescriptor& aDesc,
|
||||
ipc::UnsafeSharedMemoryHandle&& aShmem);
|
||||
RawId DeviceCreateTexture(RawId aSelfId,
|
||||
const dom::GPUTextureDescriptor& aDesc);
|
||||
const dom::GPUTextureDescriptor& aDesc,
|
||||
Maybe<layers::RemoteTextureOwnerId> aOwnerId);
|
||||
RawId TextureCreateView(RawId aSelfId, RawId aDeviceId,
|
||||
const dom::GPUTextureViewDescriptor& aDesc);
|
||||
RawId DeviceCreateSampler(RawId aSelfId,
|
||||
|
@ -105,7 +106,8 @@ class WebGPUChild final : public PWebGPUChild, public SupportsWeakPtr {
|
|||
|
||||
void DeviceCreateSwapChain(RawId aSelfId, const RGBDescriptor& aRgbDesc,
|
||||
size_t maxBufferCount,
|
||||
const layers::RemoteTextureOwnerId& aOwnerId);
|
||||
const layers::RemoteTextureOwnerId& aOwnerId,
|
||||
bool aUseExternalTextureInSwapChain);
|
||||
|
||||
void QueueOnSubmittedWorkDone(const RawId aSelfId,
|
||||
const RefPtr<dom::Promise>& aPromise);
|
||||
|
|
|
@ -7,13 +7,14 @@
|
|||
#include "mozilla/PodOperations.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/dom/WebGPUBinding.h"
|
||||
#include "mozilla/webgpu/ffi/wgpu.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/layers/ImageDataSerializer.h"
|
||||
#include "mozilla/layers/RemoteTextureMap.h"
|
||||
#include "mozilla/layers/TextureHost.h"
|
||||
#include "mozilla/layers/WebRenderImageHost.h"
|
||||
#include "mozilla/layers/WebRenderTextureHost.h"
|
||||
#include "mozilla/webgpu/ExternalTexture.h"
|
||||
#include "mozilla/webgpu/ffi/wgpu.h"
|
||||
|
||||
namespace mozilla::webgpu {
|
||||
|
||||
|
@ -21,6 +22,39 @@ const uint64_t POLL_TIME_MS = 100;
|
|||
|
||||
static mozilla::LazyLogModule sLogger("WebGPU");
|
||||
|
||||
namespace ffi {
|
||||
|
||||
extern bool wgpu_server_use_external_texture_for_swap_chain(
|
||||
void* aParam, WGPUSwapChainId aSwapChainId) {
|
||||
auto* parent = static_cast<WebGPUParent*>(aParam);
|
||||
|
||||
return parent->UseExternalTextureForSwapChain(aSwapChainId);
|
||||
}
|
||||
|
||||
extern bool wgpu_server_create_external_texture_for_swap_chain(
|
||||
void* aParam, WGPUSwapChainId aSwapChainId, WGPUDeviceId aDeviceId,
|
||||
WGPUTextureId aTextureId, uint32_t aWidth, uint32_t aHeight,
|
||||
struct WGPUTextureFormat aFormat) {
|
||||
auto* parent = static_cast<WebGPUParent*>(aParam);
|
||||
|
||||
return parent->CreateExternalTextureForSwapChain(
|
||||
aSwapChainId, aDeviceId, aTextureId, aWidth, aHeight, aFormat);
|
||||
}
|
||||
|
||||
extern void* wgpu_server_get_external_texture_handle(void* aParam,
|
||||
WGPUTextureId aId) {
|
||||
auto* parent = static_cast<WebGPUParent*>(aParam);
|
||||
|
||||
auto externalTexture = parent->GetExternalTexture(aId);
|
||||
if (!externalTexture) {
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
||||
return nullptr;
|
||||
}
|
||||
return externalTexture->GetExternalTextureHandle();
|
||||
}
|
||||
|
||||
} // namespace ffi
|
||||
|
||||
// A fixed-capacity buffer for receiving textual error messages from
|
||||
// `wgpu_bindings`.
|
||||
//
|
||||
|
@ -96,6 +130,7 @@ class PresentationData {
|
|||
NS_INLINE_DECL_REFCOUNTING(PresentationData);
|
||||
|
||||
public:
|
||||
const bool mUseExternalTextureInSwapChain;
|
||||
const RawId mDeviceId;
|
||||
const RawId mQueueId;
|
||||
const layers::RGBDescriptor mDesc;
|
||||
|
@ -105,10 +140,11 @@ class PresentationData {
|
|||
std::vector<RawId> mQueuedBufferIds MOZ_GUARDED_BY(mBuffersLock);
|
||||
Mutex mBuffersLock;
|
||||
|
||||
PresentationData(RawId aDeviceId, RawId aQueueId,
|
||||
const layers::RGBDescriptor& aDesc, uint32_t aSourcePitch,
|
||||
const nsTArray<RawId>& aBufferIds)
|
||||
: mDeviceId(aDeviceId),
|
||||
PresentationData(bool aUseExternalTextureInSwapChain, RawId aDeviceId,
|
||||
RawId aQueueId, const layers::RGBDescriptor& aDesc,
|
||||
uint32_t aSourcePitch, const nsTArray<RawId>& aBufferIds)
|
||||
: mUseExternalTextureInSwapChain(aUseExternalTextureInSwapChain),
|
||||
mDeviceId(aDeviceId),
|
||||
mQueueId(aQueueId),
|
||||
mDesc(aDesc),
|
||||
mSourcePitch(aSourcePitch),
|
||||
|
@ -250,7 +286,7 @@ static ffi::WGPUIdentityRecyclerFactory MakeFactory(void* param) {
|
|||
}
|
||||
|
||||
WebGPUParent::WebGPUParent()
|
||||
: mContext(ffi::wgpu_server_new(MakeFactory(this))) {
|
||||
: mContext(ffi::wgpu_server_new(MakeFactory(this), this)) {
|
||||
mTimer.Start(base::TimeDelta::FromMilliseconds(POLL_TIME_MS), this,
|
||||
&WebGPUParent::MaintainDevices);
|
||||
}
|
||||
|
@ -608,6 +644,11 @@ ipc::IPCResult WebGPUParent::RecvBufferDestroy(RawId aBufferId) {
|
|||
|
||||
ipc::IPCResult WebGPUParent::RecvTextureDestroy(RawId aTextureId) {
|
||||
ffi::wgpu_server_texture_drop(mContext.get(), aTextureId);
|
||||
|
||||
auto it = mExternalTextures.find(aTextureId);
|
||||
if (it != mExternalTextures.end()) {
|
||||
mExternalTextures.erase(it);
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -746,7 +787,8 @@ ipc::IPCResult WebGPUParent::RecvImplicitLayoutDestroy(
|
|||
ipc::IPCResult WebGPUParent::RecvDeviceCreateSwapChain(
|
||||
RawId aDeviceId, RawId aQueueId, const RGBDescriptor& aDesc,
|
||||
const nsTArray<RawId>& aBufferIds,
|
||||
const layers::RemoteTextureOwnerId& aOwnerId) {
|
||||
const layers::RemoteTextureOwnerId& aOwnerId,
|
||||
bool aUseExternalTextureInSwapChain) {
|
||||
switch (aDesc.format()) {
|
||||
case gfx::SurfaceFormat::R8G8B8A8:
|
||||
case gfx::SurfaceFormat::B8G8R8A8:
|
||||
|
@ -781,8 +823,9 @@ ipc::IPCResult WebGPUParent::RecvDeviceCreateSwapChain(
|
|||
// RemoteTextureMap::GetRemoteTextureForDisplayList() works synchronously.
|
||||
mRemoteTextureOwner->RegisterTextureOwner(aOwnerId, /* aIsSyncMode */ true);
|
||||
|
||||
auto data = MakeRefPtr<PresentationData>(aDeviceId, aQueueId, aDesc,
|
||||
bufferStride, aBufferIds);
|
||||
auto data =
|
||||
MakeRefPtr<PresentationData>(aUseExternalTextureInSwapChain, aDeviceId,
|
||||
aQueueId, aDesc, bufferStride, aBufferIds);
|
||||
if (!mPresentationDataMap.emplace(aOwnerId, data).second) {
|
||||
NS_ERROR("External image is already registered as WebGPU canvas!");
|
||||
}
|
||||
|
@ -1226,4 +1269,71 @@ ipc::IPCResult WebGPUParent::RecvGenerateError(const Maybe<RawId> aDeviceId,
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
bool WebGPUParent::UseExternalTextureForSwapChain(
|
||||
ffi::WGPUSwapChainId aSwapChainId) {
|
||||
auto ownerId = layers::RemoteTextureOwnerId{aSwapChainId._0};
|
||||
const auto& lookup = mPresentationDataMap.find(ownerId);
|
||||
if (lookup == mPresentationDataMap.end()) {
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
RefPtr<PresentationData> data = lookup->second.get();
|
||||
|
||||
return data->mUseExternalTextureInSwapChain;
|
||||
}
|
||||
|
||||
bool WebGPUParent::CreateExternalTextureForSwapChain(
|
||||
ffi::WGPUSwapChainId aSwapChainId, ffi::WGPUDeviceId aDeviceId,
|
||||
ffi::WGPUTextureId aTextureId, uint32_t aWidth, uint32_t aHeight,
|
||||
struct ffi::WGPUTextureFormat aFormat) {
|
||||
auto ownerId = layers::RemoteTextureOwnerId{aSwapChainId._0};
|
||||
const auto& lookup = mPresentationDataMap.find(ownerId);
|
||||
if (lookup == mPresentationDataMap.end()) {
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<PresentationData> data = lookup->second.get();
|
||||
if (!data->mUseExternalTextureInSwapChain) {
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto externalTexture =
|
||||
CreateExternalTexture(aDeviceId, aTextureId, aWidth, aHeight, aFormat);
|
||||
if (!externalTexture) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<ExternalTexture> WebGPUParent::CreateExternalTexture(
|
||||
ffi::WGPUDeviceId aDeviceId, ffi::WGPUTextureId aTextureId, uint32_t aWidth,
|
||||
uint32_t aHeight, const struct ffi::WGPUTextureFormat aFormat) {
|
||||
MOZ_RELEASE_ASSERT(mExternalTextures.find(aTextureId) ==
|
||||
mExternalTextures.end());
|
||||
|
||||
UniquePtr<ExternalTexture> texture =
|
||||
ExternalTexture::Create(aWidth, aHeight, aFormat);
|
||||
if (!texture) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<ExternalTexture> shared(texture.release());
|
||||
|
||||
mExternalTextures.emplace(aTextureId, shared);
|
||||
|
||||
return shared;
|
||||
}
|
||||
|
||||
std::shared_ptr<ExternalTexture> WebGPUParent::GetExternalTexture(
|
||||
ffi::WGPUTextureId aId) {
|
||||
auto it = mExternalTextures.find(aId);
|
||||
if (it == mExternalTextures.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
} // namespace mozilla::webgpu
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#ifndef WEBGPU_PARENT_H_
|
||||
#define WEBGPU_PARENT_H_
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "mozilla/webgpu/ffi/wgpu.h"
|
||||
#include "mozilla/webgpu/PWebGPUParent.h"
|
||||
#include "mozilla/webrender/WebRenderAPI.h"
|
||||
|
@ -22,6 +24,7 @@ class RemoteTextureOwnerClient;
|
|||
namespace webgpu {
|
||||
|
||||
class ErrorBuffer;
|
||||
class ExternalTexture;
|
||||
class PresentationData;
|
||||
|
||||
class WebGPUParent final : public PWebGPUParent {
|
||||
|
@ -75,7 +78,8 @@ class WebGPUParent final : public PWebGPUParent {
|
|||
ipc::IPCResult RecvDeviceCreateSwapChain(
|
||||
RawId aDeviceId, RawId aQueueId, const layers::RGBDescriptor& aDesc,
|
||||
const nsTArray<RawId>& aBufferIds,
|
||||
const layers::RemoteTextureOwnerId& aOwnerId);
|
||||
const layers::RemoteTextureOwnerId& aOwnerId,
|
||||
bool aUseExternalTextureInSwapChain);
|
||||
ipc::IPCResult RecvDeviceCreateShaderModule(
|
||||
RawId aDeviceId, RawId aModuleId, const nsString& aLabel,
|
||||
const nsCString& aCode, DeviceCreateShaderModuleResolver&& aOutMessage);
|
||||
|
@ -123,6 +127,21 @@ class WebGPUParent final : public PWebGPUParent {
|
|||
|
||||
BufferMapData* GetBufferMapData(RawId aBufferId);
|
||||
|
||||
bool UseExternalTextureForSwapChain(ffi::WGPUSwapChainId aSwapChainId);
|
||||
|
||||
bool CreateExternalTextureForSwapChain(ffi::WGPUSwapChainId aSwapChainId,
|
||||
ffi::WGPUDeviceId aDeviceId,
|
||||
ffi::WGPUTextureId aTextureId,
|
||||
uint32_t aWidth, uint32_t aHeight,
|
||||
struct ffi::WGPUTextureFormat aFormat);
|
||||
|
||||
std::shared_ptr<ExternalTexture> CreateExternalTexture(
|
||||
ffi::WGPUDeviceId aDeviceId, ffi::WGPUTextureId aTextureId,
|
||||
uint32_t aWidth, uint32_t aHeight,
|
||||
const struct ffi::WGPUTextureFormat aFormat);
|
||||
|
||||
std::shared_ptr<ExternalTexture> GetExternalTexture(ffi::WGPUTextureId aId);
|
||||
|
||||
private:
|
||||
void DeallocBufferShmem(RawId aBufferId);
|
||||
|
||||
|
@ -154,6 +173,9 @@ class WebGPUParent final : public PWebGPUParent {
|
|||
/// Associated stack of error scopes for each device.
|
||||
std::unordered_map<uint64_t, std::vector<ErrorScope>>
|
||||
mErrorScopeStackByDevice;
|
||||
|
||||
std::unordered_map<ffi::WGPUTextureId, std::shared_ptr<ExternalTexture>>
|
||||
mExternalTextures;
|
||||
};
|
||||
|
||||
} // namespace webgpu
|
||||
|
|
|
@ -29,6 +29,7 @@ h_and_cpp = [
|
|||
"Device",
|
||||
"DeviceLostInfo",
|
||||
"Error",
|
||||
"ExternalTexture",
|
||||
"Instance",
|
||||
"InternalError",
|
||||
"ObjectModel",
|
||||
|
@ -69,6 +70,15 @@ UNIFIED_SOURCES += [
|
|||
"ipc/WebGPUParent.cpp",
|
||||
]
|
||||
|
||||
if CONFIG["MOZ_ENABLE_D3D10_LAYER"]:
|
||||
DEFINES["MOZ_ENABLE_D3D10_LAYER"] = True
|
||||
EXPORTS.mozilla.webgpu += [
|
||||
"ExternalTextureD3D11.h",
|
||||
]
|
||||
UNIFIED_SOURCES += [
|
||||
"ExternalTextureD3D11.cpp",
|
||||
]
|
||||
|
||||
if CONFIG["CC_TYPE"] in ("clang", "clang-cl"):
|
||||
CXXFLAGS += ["-Werror=implicit-int-conversion"]
|
||||
CXXFLAGS += ["-Werror=switch"]
|
||||
|
|
|
@ -54,6 +54,10 @@ package = "wgpu-hal"
|
|||
git = "https://github.com/gfx-rs/wgpu"
|
||||
rev = "332cd0325da52675432830870584ec9766679c34"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
d3d12 = "0.7.0"
|
||||
winapi = "0.3"
|
||||
|
||||
[dependencies]
|
||||
bincode = "1"
|
||||
log = "0.4"
|
||||
|
|
|
@ -8,6 +8,8 @@ use crate::{
|
|||
QueueWriteAction, RawString, TextureAction,
|
||||
};
|
||||
|
||||
use crate::SwapChainId;
|
||||
|
||||
use wgc::{id, identity::IdentityManager};
|
||||
use wgt::{Backend, TextureFormat};
|
||||
|
||||
|
@ -504,6 +506,7 @@ 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);
|
||||
|
@ -521,6 +524,7 @@ pub extern "C" fn wgpu_client_create_texture(
|
|||
let action = DeviceAction::CreateTexture(
|
||||
id,
|
||||
desc.map_label_and_view_formats(|_| label, |_| view_formats),
|
||||
swap_chain_id.copied(),
|
||||
);
|
||||
*bb = make_byte_buf(&action);
|
||||
|
||||
|
@ -1250,3 +1254,24 @@ pub unsafe extern "C" fn wgpu_queue_write_texture(
|
|||
pub extern "C" fn wgpu_texture_format_block_size_single_aspect(format: wgt::TextureFormat) -> u32 {
|
||||
format.block_size(None).unwrap_or(0)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wgpu_client_use_external_texture_in_swapChain(
|
||||
device_id: id::DeviceId,
|
||||
format: wgt::TextureFormat,
|
||||
) -> bool {
|
||||
if device_id.backend() != wgt::Backend::Dx12 {
|
||||
return false;
|
||||
}
|
||||
|
||||
if !static_prefs::pref!("dom.webgpu.swap-chain.external-texture-dx12") {
|
||||
return false;
|
||||
}
|
||||
|
||||
let supported = match format {
|
||||
wgt::TextureFormat::Bgra8Unorm => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
supported
|
||||
}
|
||||
|
|
|
@ -118,7 +118,11 @@ struct ImplicitLayout<'a> {
|
|||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
enum DeviceAction<'a> {
|
||||
CreateTexture(id::TextureId, wgc::resource::TextureDescriptor<'a>),
|
||||
CreateTexture(
|
||||
id::TextureId,
|
||||
wgc::resource::TextureDescriptor<'a>,
|
||||
Option<SwapChainId>,
|
||||
),
|
||||
CreateSampler(id::SamplerId, wgc::resource::SamplerDescriptor<'a>),
|
||||
CreateBindGroupLayout(
|
||||
id::BindGroupLayoutId,
|
||||
|
@ -222,3 +226,7 @@ impl<'a> ImageDataLayout<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct SwapChainId(pub u64);
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::{
|
|||
error::{ErrMsg, ErrorBuffer, ErrorBufferType},
|
||||
identity::IdentityRecyclerFactory,
|
||||
wgpu_string, AdapterInformation, ByteBuf, CommandEncoderAction, DeviceAction, DropAction,
|
||||
QueueWriteAction, TextureAction,
|
||||
QueueWriteAction, SwapChainId, TextureAction,
|
||||
};
|
||||
|
||||
use nsstring::{nsACString, nsCString, nsString};
|
||||
|
@ -15,9 +15,15 @@ use wgc::{gfx_select, id};
|
|||
use wgc::{pipeline::CreateShaderModuleError, resource::BufferAccessError};
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::os::raw::c_void;
|
||||
use std::slice;
|
||||
use std::sync::atomic::{AtomicU32, Ordering};
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
use winapi::um::d3d12 as d3d12_ty;
|
||||
#[cfg(target_os = "windows")]
|
||||
use winapi::Interface;
|
||||
|
||||
// The seemingly redundant u64 suffixes help cbindgen with generating the right C++ code.
|
||||
// See https://github.com/mozilla/cbindgen/issues/849.
|
||||
|
||||
|
@ -42,17 +48,24 @@ fn restrict_limits(limits: wgt::Limits) -> wgt::Limits {
|
|||
}
|
||||
|
||||
// hide wgc's global in private
|
||||
pub struct Global(wgc::global::Global<IdentityRecyclerFactory>);
|
||||
pub struct Global {
|
||||
global: wgc::global::Global<IdentityRecyclerFactory>,
|
||||
#[allow(dead_code)]
|
||||
owner: *mut c_void,
|
||||
}
|
||||
|
||||
impl std::ops::Deref for Global {
|
||||
type Target = wgc::global::Global<IdentityRecyclerFactory>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
&self.global
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wgpu_server_new(factory: IdentityRecyclerFactory) -> *mut Global {
|
||||
pub extern "C" fn wgpu_server_new(
|
||||
factory: IdentityRecyclerFactory,
|
||||
owner: *mut c_void,
|
||||
) -> *mut Global {
|
||||
log::info!("Initializing WGPU server");
|
||||
let backends_pref = static_prefs::pref!("dom.webgpu.wgpu-backend").to_string();
|
||||
let backends = if backends_pref.is_empty() {
|
||||
|
@ -64,7 +77,7 @@ pub extern "C" fn wgpu_server_new(factory: IdentityRecyclerFactory) -> *mut Glob
|
|||
);
|
||||
wgc::instance::parse_backends_from_comma_list(&backends_pref)
|
||||
};
|
||||
let global = Global(wgc::global::Global::new(
|
||||
let global = wgc::global::Global::new(
|
||||
"wgpu",
|
||||
factory,
|
||||
wgt::InstanceDescriptor {
|
||||
|
@ -72,7 +85,8 @@ pub extern "C" fn wgpu_server_new(factory: IdentityRecyclerFactory) -> *mut Glob
|
|||
dx12_shader_compiler: wgt::Dx12Compiler::Fxc,
|
||||
gles_minor_version: wgt::Gles3MinorVersion::Automatic,
|
||||
},
|
||||
));
|
||||
);
|
||||
let global = Global { global, owner };
|
||||
Box::into_raw(Box::new(global))
|
||||
}
|
||||
|
||||
|
@ -413,6 +427,29 @@ pub extern "C" fn wgpu_server_buffer_drop(global: &Global, self_id: id::BufferId
|
|||
gfx_select!(self_id => global.buffer_drop(self_id, false));
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
#[allow(dead_code)]
|
||||
fn wgpu_server_use_external_texture_for_swap_chain(
|
||||
param: *mut c_void,
|
||||
swap_chain_id: SwapChainId,
|
||||
) -> bool;
|
||||
#[allow(dead_code)]
|
||||
fn wgpu_server_create_external_texture_for_swap_chain(
|
||||
param: *mut c_void,
|
||||
swap_chain_id: SwapChainId,
|
||||
device_id: id::DeviceId,
|
||||
texture_id: id::TextureId,
|
||||
width: u32,
|
||||
height: u32,
|
||||
format: wgt::TextureFormat,
|
||||
) -> bool;
|
||||
#[allow(dead_code)]
|
||||
fn wgpu_server_get_external_texture_handle(
|
||||
param: *mut c_void,
|
||||
id: id::TextureId,
|
||||
) -> *mut c_void;
|
||||
}
|
||||
|
||||
impl Global {
|
||||
fn device_action<A: wgc::hal_api::HalApi>(
|
||||
&self,
|
||||
|
@ -421,7 +458,7 @@ impl Global {
|
|||
mut error_buf: ErrorBuffer,
|
||||
) {
|
||||
match action {
|
||||
DeviceAction::CreateTexture(id, desc) => {
|
||||
DeviceAction::CreateTexture(id, desc, swap_chain_id) => {
|
||||
let max = MAX_TEXTURE_EXTENT;
|
||||
if desc.size.width > max
|
||||
|| desc.size.height > max
|
||||
|
@ -434,6 +471,98 @@ impl Global {
|
|||
});
|
||||
return;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let use_external_texture = if swap_chain_id.is_some() {
|
||||
unsafe {
|
||||
wgpu_server_use_external_texture_for_swap_chain(
|
||||
self.owner,
|
||||
swap_chain_id.unwrap(),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if use_external_texture && self_id.backend() == wgt::Backend::Dx12 {
|
||||
let ret = unsafe {
|
||||
wgpu_server_create_external_texture_for_swap_chain(
|
||||
self.owner,
|
||||
swap_chain_id.unwrap(),
|
||||
self_id,
|
||||
id,
|
||||
desc.size.width,
|
||||
desc.size.height,
|
||||
desc.format,
|
||||
)
|
||||
};
|
||||
if ret != true {
|
||||
error_buf.init(ErrMsg {
|
||||
message: "Failed to create external texture",
|
||||
r#type: ErrorBufferType::Internal,
|
||||
});
|
||||
}
|
||||
|
||||
let dx12_device = unsafe {
|
||||
self.device_as_hal::<wgc::api::Dx12, _, d3d12::Device>(
|
||||
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() {
|
||||
error_buf.init(ErrMsg {
|
||||
message: "Failed to get external texture handle",
|
||||
r#type: ErrorBufferType::Internal,
|
||||
});
|
||||
}
|
||||
let mut resource = d3d12::Resource::null();
|
||||
let hr = unsafe {
|
||||
dx12_device.OpenSharedHandle(
|
||||
handle,
|
||||
&d3d12_ty::ID3D12Resource::uuidof(),
|
||||
resource.mut_void(),
|
||||
)
|
||||
};
|
||||
if hr != 0 {
|
||||
error_buf.init(ErrMsg {
|
||||
message: "Failed to open shared handle",
|
||||
r#type: ErrorBufferType::Internal,
|
||||
});
|
||||
}
|
||||
|
||||
let hal_texture = unsafe {
|
||||
<wgh::api::Dx12 as wgh::Api>::Device::texture_from_raw(
|
||||
resource,
|
||||
wgt::TextureFormat::Bgra8Unorm,
|
||||
wgt::TextureDimension::D2,
|
||||
desc.size,
|
||||
1,
|
||||
1,
|
||||
)
|
||||
};
|
||||
let (_, error) = unsafe {
|
||||
self.create_texture_from_hal::<wgh::api::Dx12>(
|
||||
hal_texture,
|
||||
self_id,
|
||||
&desc,
|
||||
id,
|
||||
)
|
||||
};
|
||||
if let Some(err) = error {
|
||||
error_buf.init(err);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if swap_chain_id.is_some() && self_id.backend() != wgt::Backend::Dx12 {
|
||||
debug_assert!(false, "Unexpected to be called");
|
||||
}
|
||||
|
||||
let (_, error) = self.device_create_texture::<A>(self_id, &desc, id);
|
||||
if let Some(err) = error {
|
||||
error_buf.init(err);
|
||||
|
|
|
@ -4614,6 +4614,12 @@
|
|||
mirror: always
|
||||
rust: true
|
||||
|
||||
- name: dom.webgpu.swap-chain.external-texture-dx12
|
||||
type: RelaxedAtomicBool
|
||||
value: false
|
||||
mirror: always
|
||||
rust: true
|
||||
|
||||
# Is support for HTMLInputElement.webkitEntries enabled?
|
||||
- name: dom.webkitBlink.filesystem.enabled
|
||||
type: bool
|
||||
|
|
Загрузка…
Ссылка в новой задаче