0

SharedImage: Support StorageBinding for BGRA8Unorm shared images on D3D

This patch adds BGRA8Unorm as the allowed usage of D3D shared images as
BGRA8Unorm can be used as storage textures with WebGPU extension
'bgra8unorm-storage' is enabled.

Bug: dawn:1641, chromium:1418897
Change-Id: I7caef95f22d40e9f188e70bf29136cb90110ac82
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4290629
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Cr-Commit-Position: refs/heads/main@{#1111954}
This commit is contained in:
Jiawei Shao
2023-03-02 01:02:15 +00:00
committed by Chromium LUCI CQ
parent 7e57878f2e
commit 5a245fc75c
4 changed files with 66 additions and 6 deletions

@ -618,6 +618,7 @@ bool D3DImageBacking::ReadbackToMemory(const std::vector<SkPixmap>& pixmaps) {
}
WGPUTextureUsageFlags D3DImageBacking::GetAllowedDawnUsages(
WGPUDevice device,
const WGPUTextureFormat wgpu_format) const {
// TODO(crbug.com/2709243): Figure out other SI flags, if any.
DCHECK(usage() & gpu::SHARED_IMAGE_USAGE_WEBGPU);
@ -625,10 +626,26 @@ WGPUTextureUsageFlags D3DImageBacking::GetAllowedDawnUsages(
WGPUTextureUsage_CopySrc | WGPUTextureUsage_CopyDst |
WGPUTextureUsage_TextureBinding | WGPUTextureUsage_RenderAttachment;
switch (wgpu_format) {
case WGPUTextureFormat_BGRA8Unorm:
case WGPUTextureFormat_R8Unorm:
case WGPUTextureFormat_RG8Unorm:
return kBasicUsage;
case WGPUTextureFormat_BGRA8Unorm: {
if (usage() & gpu::SHARED_IMAGE_USAGE_WEBGPU_STORAGE_TEXTURE) {
if (dawn::native::GetProcs().deviceHasFeature(
device, WGPUFeatureName_BGRA8UnormStorage)) {
return kBasicUsage | WGPUTextureUsage_StorageBinding;
} else {
// We cannot use BGRA8Unorm textures as storage textures when
// the feature BGRA8UnormStorage is not enabled.
LOG(ERROR) << "StorageBinding is not supported for "
<< WGPUTextureFormat_BGRA8Unorm << " when the feature "
<< WGPUFeatureName_BGRA8UnormStorage << " is not enabled";
return WGPUTextureUsage_None;
}
} else {
return kBasicUsage;
}
}
case WGPUTextureFormat_RGBA8Unorm:
case WGPUTextureFormat_RGBA16Float: {
if (usage() & gpu::SHARED_IMAGE_USAGE_WEBGPU_STORAGE_TEXTURE) {
@ -673,7 +690,8 @@ std::unique_ptr<DawnImageRepresentation> D3DImageBacking::ProduceDawn(
return nullptr;
}
WGPUTextureUsageFlags allowed_usage = GetAllowedDawnUsages(wgpu_format);
WGPUTextureUsageFlags allowed_usage =
GetAllowedDawnUsages(device, wgpu_format);
if (allowed_usage == WGPUTextureUsage_None) {
LOG(ERROR) << "Allowed WGPUTextureUsage is unknown for WGPUTextureFormat: "
<< wgpu_format;

@ -210,6 +210,7 @@ class GPU_GLES2_EXPORT D3DImageBacking
bool is_back_buffer = false);
WGPUTextureUsageFlags GetAllowedDawnUsages(
WGPUDevice device,
const WGPUTextureFormat wgpu_format) const;
gl::GLImage* GetGLImage() const;

@ -387,12 +387,31 @@ std::unique_ptr<SharedImageBacking> D3DImageBackingFactory::CreateSharedImage(
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
// WebGPU can use RGBA_8888 and RGBA_16 for STORAGE_BINDING.
if ((usage & gpu::SHARED_IMAGE_USAGE_WEBGPU_STORAGE_TEXTURE) &&
(format == viz::SinglePlaneFormat::kRGBA_8888 ||
format == viz::SinglePlaneFormat::kRGBA_F16)) {
format.is_single_plane()) {
DCHECK(usage & gpu::SHARED_IMAGE_USAGE_WEBGPU);
desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
switch (format.resource_format()) {
// WebGPU can use RGBA_8888 and RGBA_16 for STORAGE_BINDING.
case viz::ResourceFormat::RGBA_8888:
case viz::ResourceFormat::RGBA_F16:
desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
break;
// WebGPU can use BGRA_8888 for STORAGE_BINDING when BGRA_8888 is
// supported as UAV.
case viz::ResourceFormat::BGRA_8888: {
if (SupportsBGRA8UnormStorage()) {
desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
} else {
LOG(ERROR)
<< "D3D11_BIND_UNORDERED_ACCESS is not supported on BGRA_8888";
return nullptr;
}
break;
}
default:
break;
}
}
if (is_shm_gmb) {
// D3D doesn't support mappable+default YUV textures.
@ -521,6 +540,26 @@ bool D3DImageBackingFactory::UseMapOnDefaultTextures() {
return map_on_default_textures_.value();
}
bool D3DImageBackingFactory::SupportsBGRA8UnormStorage() {
if (!supports_bgra8unorm_storage_.has_value()) {
D3D11_FEATURE_DATA_FORMAT_SUPPORT bgra8UnormSupport = {};
bgra8UnormSupport.InFormat = DXGI_FORMAT_B8G8R8A8_UNORM;
HRESULT hr = d3d11_device_->CheckFeatureSupport(
D3D11_FEATURE_FORMAT_SUPPORT, &bgra8UnormSupport,
sizeof(D3D11_FEATURE_DATA_FORMAT_SUPPORT));
if (SUCCEEDED(hr)) {
supports_bgra8unorm_storage_.emplace(
bgra8UnormSupport.OutFormatSupport &
D3D11_FORMAT_SUPPORT_TYPED_UNORDERED_ACCESS_VIEW);
} else {
VLOG(1) << "Failed to retrieve D3D11_FEATURE_FORMAT_SUPPORT. hr = "
<< std::hex << hr;
supports_bgra8unorm_storage_.emplace(false);
}
}
return supports_bgra8unorm_storage_.value();
}
bool D3DImageBackingFactory::IsSupported(uint32_t usage,
viz::SharedImageFormat format,
const gfx::Size& size,

@ -140,9 +140,11 @@ class GPU_GLES2_EXPORT D3DImageBackingFactory
SkAlphaType alpha_type,
uint32_t usage);
bool UseMapOnDefaultTextures();
bool SupportsBGRA8UnormStorage();
Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device_;
absl::optional<bool> map_on_default_textures_;
absl::optional<bool> supports_bgra8unorm_storage_;
scoped_refptr<DXGISharedHandleManager> dxgi_shared_handle_manager_;
};