From 30014df55f9ff0f13b170b6ca54889094009e973 Mon Sep 17 00:00:00 2001 From: sotaro Date: Thu, 9 Nov 2023 00:42:41 +0000 Subject: [PATCH] Bug 1863106 - Set D3D11_BIND_UNORDERED_ACCESS if texture usage has STORAGE_BINDING r=lsalzman wgpu dx12 requests to Texture that if its usage has STORAGE_BINDING, D3D12 resource needs to have D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS. The equivalent of D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS in D3D11 is D3D11_BIND_UNORDERED_ACCESS. Therefore, D3D11 textures in ExternalTextureD3D11 also require D3D11_BIND_UNORDERED_ACCESS if STORAGE_BINDING is used. Differential Revision: https://phabricator.services.mozilla.com/D192976 --- dom/webgpu/ExternalTexture.cpp | 10 ++++++---- dom/webgpu/ExternalTexture.h | 7 +++++-- dom/webgpu/ExternalTextureD3D11.cpp | 14 ++++++++++---- dom/webgpu/ExternalTextureD3D11.h | 4 +++- dom/webgpu/ipc/WebGPUParent.cpp | 17 +++++++++-------- dom/webgpu/ipc/WebGPUParent.h | 6 ++++-- gfx/wgpu_bindings/src/server.rs | 2 ++ 7 files changed, 39 insertions(+), 21 deletions(-) diff --git a/dom/webgpu/ExternalTexture.cpp b/dom/webgpu/ExternalTexture.cpp index ba6374cb53bd..c29c8190e4b7 100644 --- a/dom/webgpu/ExternalTexture.cpp +++ b/dom/webgpu/ExternalTexture.cpp @@ -14,17 +14,19 @@ namespace mozilla::webgpu { // static UniquePtr ExternalTexture::Create( const uint32_t aWidth, const uint32_t aHeight, - const struct ffi::WGPUTextureFormat aFormat) { + const struct ffi::WGPUTextureFormat aFormat, + const ffi::WGPUTextureUsages aUsage) { UniquePtr texture; #ifdef XP_WIN - texture = ExternalTextureD3D11::Create(aWidth, aHeight, aFormat); + texture = ExternalTextureD3D11::Create(aWidth, aHeight, aFormat, aUsage); #endif return texture; } ExternalTexture::ExternalTexture(const uint32_t aWidth, const uint32_t aHeight, - const struct ffi::WGPUTextureFormat aFormat) - : mWidth(aWidth), mHeight(aHeight), mFormat(aFormat) {} + const struct ffi::WGPUTextureFormat aFormat, + const ffi::WGPUTextureUsages aUsage) + : mWidth(aWidth), mHeight(aHeight), mFormat(aFormat), mUsage(aUsage) {} ExternalTexture::~ExternalTexture() {} diff --git a/dom/webgpu/ExternalTexture.h b/dom/webgpu/ExternalTexture.h index be9ca937a51e..25e5fc5abfa1 100644 --- a/dom/webgpu/ExternalTexture.h +++ b/dom/webgpu/ExternalTexture.h @@ -24,10 +24,12 @@ class ExternalTexture { public: static UniquePtr Create( const uint32_t aWidth, const uint32_t aHeight, - const struct ffi::WGPUTextureFormat aFormat); + const struct ffi::WGPUTextureFormat aFormat, + const ffi::WGPUTextureUsages aUsage); ExternalTexture(const uint32_t aWidth, const uint32_t aHeight, - const struct ffi::WGPUTextureFormat aFormat); + const struct ffi::WGPUTextureFormat aFormat, + const ffi::WGPUTextureUsages aUsage); virtual ~ExternalTexture(); virtual void* GetExternalTextureHandle() { return nullptr; } @@ -42,6 +44,7 @@ class ExternalTexture { const uint32_t mWidth; const uint32_t mHeight; const struct ffi::WGPUTextureFormat mFormat; + const ffi::WGPUTextureUsages mUsage; }; } // namespace webgpu diff --git a/dom/webgpu/ExternalTextureD3D11.cpp b/dom/webgpu/ExternalTextureD3D11.cpp index f7d5d394706b..265ebe9d3093 100644 --- a/dom/webgpu/ExternalTextureD3D11.cpp +++ b/dom/webgpu/ExternalTextureD3D11.cpp @@ -16,7 +16,8 @@ namespace mozilla::webgpu { // static UniquePtr ExternalTextureD3D11::Create( const uint32_t aWidth, const uint32_t aHeight, - const struct ffi::WGPUTextureFormat aFormat) { + const struct ffi::WGPUTextureFormat aFormat, + const ffi::WGPUTextureUsages aUsage) { const RefPtr d3d11Device = gfx::DeviceManagerDx::Get()->GetCompositorDevice(); if (!d3d11Device) { @@ -33,6 +34,10 @@ UniquePtr ExternalTextureD3D11::Create( DXGI_FORMAT_B8G8R8A8_UNORM, aWidth, aHeight, 1, 1, D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET); + if (aUsage & WGPUTextureUsages_STORAGE_BINDING) { + desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS; + } + desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED; RefPtr texture; @@ -42,14 +47,15 @@ UniquePtr ExternalTextureD3D11::Create( gfxCriticalNoteOnce << "CreateTexture2D failed: " << gfx::hexa(hr); return nullptr; } - return MakeUnique(aWidth, aHeight, aFormat, texture); + return MakeUnique(aWidth, aHeight, aFormat, aUsage, + texture); } ExternalTextureD3D11::ExternalTextureD3D11( const uint32_t aWidth, const uint32_t aHeight, const struct ffi::WGPUTextureFormat aFormat, - RefPtr aTexture) - : ExternalTexture(aWidth, aHeight, aFormat), mTexture(aTexture) { + const ffi::WGPUTextureUsages aUsage, RefPtr aTexture) + : ExternalTexture(aWidth, aHeight, aFormat, aUsage), mTexture(aTexture) { MOZ_ASSERT(mTexture); } diff --git a/dom/webgpu/ExternalTextureD3D11.h b/dom/webgpu/ExternalTextureD3D11.h index 1d24a7064376..4eba0e02888c 100644 --- a/dom/webgpu/ExternalTextureD3D11.h +++ b/dom/webgpu/ExternalTextureD3D11.h @@ -18,10 +18,12 @@ class ExternalTextureD3D11 final : public ExternalTexture { public: static UniquePtr Create( const uint32_t aWidth, const uint32_t aHeight, - const struct ffi::WGPUTextureFormat aFormat); + const struct ffi::WGPUTextureFormat aFormat, + const ffi::WGPUTextureUsages aUsage); ExternalTextureD3D11(const uint32_t aWidth, const uint32_t aHeight, const struct ffi::WGPUTextureFormat aFormat, + const ffi::WGPUTextureUsages aUsage, RefPtr aTexture); virtual ~ExternalTextureD3D11(); diff --git a/dom/webgpu/ipc/WebGPUParent.cpp b/dom/webgpu/ipc/WebGPUParent.cpp index b6a46c303305..5814390734ef 100644 --- a/dom/webgpu/ipc/WebGPUParent.cpp +++ b/dom/webgpu/ipc/WebGPUParent.cpp @@ -39,11 +39,11 @@ extern bool wgpu_server_use_external_texture_for_swap_chain( extern bool wgpu_server_ensure_external_texture_for_swap_chain( void* aParam, WGPUSwapChainId aSwapChainId, WGPUDeviceId aDeviceId, WGPUTextureId aTextureId, uint32_t aWidth, uint32_t aHeight, - struct WGPUTextureFormat aFormat) { + struct WGPUTextureFormat aFormat, WGPUTextureUsages aUsage) { auto* parent = static_cast(aParam); return parent->EnsureExternalTextureForSwapChain( - aSwapChainId, aDeviceId, aTextureId, aWidth, aHeight, aFormat); + aSwapChainId, aDeviceId, aTextureId, aWidth, aHeight, aFormat, aUsage); } extern void* wgpu_server_get_external_texture_handle(void* aParam, @@ -1401,7 +1401,7 @@ bool WebGPUParent::UseExternalTextureForSwapChain( bool WebGPUParent::EnsureExternalTextureForSwapChain( ffi::WGPUSwapChainId aSwapChainId, ffi::WGPUDeviceId aDeviceId, ffi::WGPUTextureId aTextureId, uint32_t aWidth, uint32_t aHeight, - struct ffi::WGPUTextureFormat aFormat) { + struct ffi::WGPUTextureFormat aFormat, ffi::WGPUTextureUsages aUsage) { auto ownerId = layers::RemoteTextureOwnerId{aSwapChainId._0}; const auto& lookup = mPresentationDataMap.find(ownerId); if (lookup == mPresentationDataMap.end()) { @@ -1421,7 +1421,7 @@ bool WebGPUParent::EnsureExternalTextureForSwapChain( data->mRecycledExternalTextures.front(); // Check if the texture is recyclable. if (texture->mWidth == aWidth && texture->mHeight == aHeight && - texture->mFormat.tag == aFormat.tag) { + texture->mFormat.tag == aFormat.tag && texture->mUsage == aUsage) { data->mRecycledExternalTextures.pop_front(); mExternalTextures.emplace(aTextureId, texture); return true; @@ -1429,8 +1429,8 @@ bool WebGPUParent::EnsureExternalTextureForSwapChain( data->mRecycledExternalTextures.clear(); } - auto externalTexture = - CreateExternalTexture(aDeviceId, aTextureId, aWidth, aHeight, aFormat); + auto externalTexture = CreateExternalTexture(aDeviceId, aTextureId, aWidth, + aHeight, aFormat, aUsage); if (!externalTexture) { return false; } @@ -1439,12 +1439,13 @@ bool WebGPUParent::EnsureExternalTextureForSwapChain( std::shared_ptr WebGPUParent::CreateExternalTexture( ffi::WGPUDeviceId aDeviceId, ffi::WGPUTextureId aTextureId, uint32_t aWidth, - uint32_t aHeight, const struct ffi::WGPUTextureFormat aFormat) { + uint32_t aHeight, const struct ffi::WGPUTextureFormat aFormat, + ffi::WGPUTextureUsages aUsage) { MOZ_RELEASE_ASSERT(mExternalTextures.find(aTextureId) == mExternalTextures.end()); UniquePtr texture = - ExternalTexture::Create(aWidth, aHeight, aFormat); + ExternalTexture::Create(aWidth, aHeight, aFormat, aUsage); if (!texture) { MOZ_ASSERT_UNREACHABLE("unexpected to be called"); return nullptr; diff --git a/dom/webgpu/ipc/WebGPUParent.h b/dom/webgpu/ipc/WebGPUParent.h index 28c5c572ee85..2e1138e259ce 100644 --- a/dom/webgpu/ipc/WebGPUParent.h +++ b/dom/webgpu/ipc/WebGPUParent.h @@ -135,12 +135,14 @@ class WebGPUParent final : public PWebGPUParent { ffi::WGPUDeviceId aDeviceId, ffi::WGPUTextureId aTextureId, uint32_t aWidth, uint32_t aHeight, - struct ffi::WGPUTextureFormat aFormat); + struct ffi::WGPUTextureFormat aFormat, + ffi::WGPUTextureUsages aUsage); std::shared_ptr CreateExternalTexture( ffi::WGPUDeviceId aDeviceId, ffi::WGPUTextureId aTextureId, uint32_t aWidth, uint32_t aHeight, - const struct ffi::WGPUTextureFormat aFormat); + const struct ffi::WGPUTextureFormat aFormat, + ffi::WGPUTextureUsages aUsage); std::shared_ptr GetExternalTexture(ffi::WGPUTextureId aId); diff --git a/gfx/wgpu_bindings/src/server.rs b/gfx/wgpu_bindings/src/server.rs index 32d1915a0a2c..7f917b593a3a 100644 --- a/gfx/wgpu_bindings/src/server.rs +++ b/gfx/wgpu_bindings/src/server.rs @@ -509,6 +509,7 @@ extern "C" { width: u32, height: u32, format: wgt::TextureFormat, + usage: wgt::TextureUsages, ) -> bool; #[allow(dead_code)] fn wgpu_server_get_external_texture_handle( @@ -563,6 +564,7 @@ impl Global { desc.size.width, desc.size.height, desc.format, + desc.usage, ) }; if ret != true {