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
This commit is contained in:
sotaro 2023-11-09 00:42:41 +00:00
parent 33e4b4bf8e
commit 30014df55f
7 changed files with 39 additions and 21 deletions

View file

@ -14,17 +14,19 @@ namespace mozilla::webgpu {
// static
UniquePtr<ExternalTexture> 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<ExternalTexture> 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() {}

View file

@ -24,10 +24,12 @@ class ExternalTexture {
public:
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);
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

View file

@ -16,7 +16,8 @@ namespace mozilla::webgpu {
// static
UniquePtr<ExternalTextureD3D11> 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<ID3D11Device> d3d11Device =
gfx::DeviceManagerDx::Get()->GetCompositorDevice();
if (!d3d11Device) {
@ -33,6 +34,10 @@ UniquePtr<ExternalTextureD3D11> 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<ID3D11Texture2D> texture;
@ -42,14 +47,15 @@ UniquePtr<ExternalTextureD3D11> ExternalTextureD3D11::Create(
gfxCriticalNoteOnce << "CreateTexture2D failed: " << gfx::hexa(hr);
return nullptr;
}
return MakeUnique<ExternalTextureD3D11>(aWidth, aHeight, aFormat, texture);
return MakeUnique<ExternalTextureD3D11>(aWidth, aHeight, aFormat, aUsage,
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) {
const ffi::WGPUTextureUsages aUsage, RefPtr<ID3D11Texture2D> aTexture)
: ExternalTexture(aWidth, aHeight, aFormat, aUsage), mTexture(aTexture) {
MOZ_ASSERT(mTexture);
}

View file

@ -18,10 +18,12 @@ class ExternalTextureD3D11 final : public ExternalTexture {
public:
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);
ExternalTextureD3D11(const uint32_t aWidth, const uint32_t aHeight,
const struct ffi::WGPUTextureFormat aFormat,
const ffi::WGPUTextureUsages aUsage,
RefPtr<ID3D11Texture2D> aTexture);
virtual ~ExternalTextureD3D11();

View file

@ -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<WebGPUParent*>(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<ExternalTexture> 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<ExternalTexture> texture =
ExternalTexture::Create(aWidth, aHeight, aFormat);
ExternalTexture::Create(aWidth, aHeight, aFormat, aUsage);
if (!texture) {
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
return nullptr;

View file

@ -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<ExternalTexture> 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<ExternalTexture> GetExternalTexture(ffi::WGPUTextureId aId);

View file

@ -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 {