Commit 72775371 authored by jchen10's avatar jchen10 Committed by Commit Bot

Add disable_decode_swap_chain workaround

Switching quickly through Instagram videos may hit an Intel driver
bug on some Gen9 platforms with DecodeSwapChain turned on. This also
cleans up 'supports_nv12_decode_swap_chain' in CopyTextureSelector.

Bug: 1107403
Change-Id: I5deb4414295eecad8ae74bd25f8c6d3fb50a5009
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2332048Reviewed-by: default avatarFrank Liberato <liberato@chromium.org>
Reviewed-by: default avatarZhenyao Mo <zmo@chromium.org>
Reviewed-by: default avatarSunny Sachanandani <sunnyps@chromium.org>
Commit-Queue: Jie A Chen <jie.a.chen@intel.com>
Cr-Commit-Position: refs/heads/master@{#798062}
parent 05b0a1c1
......@@ -3457,6 +3457,22 @@
"features": [
"disable_accelerated_vp8_decode"
]
},
{
"id": 345,
"description": "Disable DecodeSwapChain for Intel Gen9 and older devices",
"cr_bugs": [1107403],
"os": {
"type": "win"
},
"vendor_id": "0x8086",
"intel_gpu_generation": {
"op": "<=",
"value": "9"
},
"features": [
"disable_decode_swap_chain"
]
}
]
}
......@@ -21,6 +21,7 @@ disable_blend_equation_advanced
disable_chromium_framebuffer_multisample
disable_d3d11
disable_d3d11_video_decoder
disable_decode_swap_chain
disable_delayed_copy_nv12
disable_depth_texture
disable_direct_composition
......
......@@ -46,6 +46,8 @@
#endif
#if defined(OS_WIN)
#include "gpu/config/gpu_driver_bug_workarounds.h"
#include "ui/gl/direct_composition_surface_win.h"
#include "ui/gl/gl_surface_egl.h"
#endif
......@@ -574,6 +576,11 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line,
if (!watchdog_thread_)
watchdog_init.SetGpuWatchdogPtr(nullptr);
#if defined(OS_WIN)
if (gpu_feature_info_.IsWorkaroundEnabled(DISABLE_DECODE_SWAP_CHAIN))
gl::DirectCompositionSurfaceWin::DisableDecodeSwapChain();
#endif
return true;
}
......@@ -710,6 +717,11 @@ void GpuInit::InitializeInProcess(base::CommandLine* command_line,
DisableInProcessGpuVulkan(&gpu_feature_info_, &gpu_preferences_);
#if defined(OS_WIN)
if (gpu_feature_info_.IsWorkaroundEnabled(DISABLE_DECODE_SWAP_CHAIN))
gl::DirectCompositionSurfaceWin::DisableDecodeSwapChain();
#endif
UMA_HISTOGRAM_ENUMERATION("GPU.GLImplementation", gl::GetGLImplementation());
}
#endif // OS_ANDROID
......
......@@ -117,9 +117,9 @@ void D3D11DecoderConfigurator::SetUpTextureDescriptor(bool supports_swap_chain,
// TODO(sunnyps): Find a workaround for when the decoder moves to its own
// thread and D3D device. See https://crbug.com/911847
// TODO(liberato): This depends on the configuration of the TextureSelector,
// to some degree. If it's copying, then it can be set up to use our device
// to make the copy, and this can always be unset. If it's binding, then it
// depends on whether we're on the angle device or not.
// to some degree. We should unset the flag only if it's binding and the
// decode swap chain is supported, as Intel driver is buggy on Gen9 and older
// devices without the flag. See https://crbug.com/1107403
output_texture_desc_.MiscFlags =
supports_swap_chain ? 0 : D3D11_RESOURCE_MISC_SHARED;
......
......@@ -12,16 +12,12 @@
#include "media/gpu/windows/d3d11_copying_texture_wrapper.h"
#include "media/gpu/windows/d3d11_video_device_format_support.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gl/direct_composition_surface_win.h"
namespace media {
TextureSelector::TextureSelector(VideoPixelFormat pixfmt,
DXGI_FORMAT output_dxgifmt,
bool supports_swap_chain)
: pixel_format_(pixfmt),
output_dxgifmt_(output_dxgifmt),
supports_swap_chain_(supports_swap_chain) {}
DXGI_FORMAT output_dxgifmt)
: pixel_format_(pixfmt), output_dxgifmt_(output_dxgifmt) {}
bool SupportsZeroCopy(const gpu::GpuPreferences& preferences,
const gpu::GpuDriverBugWorkarounds& workarounds) {
......@@ -42,9 +38,6 @@ std::unique_ptr<TextureSelector> TextureSelector::Create(
TextureSelector::HDRMode hdr_output_mode,
const FormatSupportChecker* format_checker,
MediaLog* media_log) {
bool supports_nv12_decode_swap_chain =
gl::DirectCompositionSurfaceWin::IsDecodeSwapChainSupported();
VideoPixelFormat output_pixel_format;
DXGI_FORMAT output_dxgi_format;
base::Optional<gfx::ColorSpace> output_color_space;
......@@ -165,16 +158,14 @@ std::unique_ptr<TextureSelector> TextureSelector::Create(
MEDIA_LOG(INFO, media_log) << "D3D11VideoDecoder is copying textures";
return std::make_unique<CopyTextureSelector>(
output_pixel_format, decoder_output_format, output_dxgi_format,
output_color_space,
supports_nv12_decode_swap_chain); // TODO(tmathmeyer) false always?
output_color_space);
} else {
MEDIA_LOG(INFO, media_log) << "D3D11VideoDecoder is binding textures";
// Binding can't change the color space. The consumer has to do it, if they
// want to.
DCHECK(!output_color_space);
return std::make_unique<TextureSelector>(output_pixel_format,
output_dxgi_format,
supports_nv12_decode_swap_chain);
output_dxgi_format);
}
}
......@@ -195,9 +186,8 @@ CopyTextureSelector::CopyTextureSelector(
VideoPixelFormat pixfmt,
DXGI_FORMAT input_dxgifmt,
DXGI_FORMAT output_dxgifmt,
base::Optional<gfx::ColorSpace> output_color_space,
bool supports_swap_chain)
: TextureSelector(pixfmt, output_dxgifmt, supports_swap_chain),
base::Optional<gfx::ColorSpace> output_color_space)
: TextureSelector(pixfmt, output_dxgifmt),
output_color_space_(std::move(output_color_space)) {}
CopyTextureSelector::~CopyTextureSelector() = default;
......@@ -216,13 +206,6 @@ std::unique_ptr<Texture2DWrapper> CopyTextureSelector::CreateTextureWrapper(
texture_desc.Usage = D3D11_USAGE_DEFAULT;
texture_desc.BindFlags =
D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
// Decode swap chains do not support shared resources.
// TODO(sunnyps): Find a workaround for when the decoder moves to its own
// thread and D3D device. See https://crbug.com/911847
texture_desc.MiscFlags =
supports_swap_chain_ ? 0 : D3D11_RESOURCE_MISC_SHARED;
texture_desc.Width = size.width();
texture_desc.Height = size.height();
......
......@@ -30,9 +30,7 @@ class MEDIA_GPU_EXPORT TextureSelector {
kSDROrHDR = 1,
};
TextureSelector(VideoPixelFormat pixfmt,
DXGI_FORMAT output_dxgifmt,
bool supports_swap_chain);
TextureSelector(VideoPixelFormat pixfmt, DXGI_FORMAT output_dxgifmt);
virtual ~TextureSelector() = default;
static std::unique_ptr<TextureSelector> Create(
......@@ -59,7 +57,6 @@ class MEDIA_GPU_EXPORT TextureSelector {
const VideoPixelFormat pixel_format_;
const DXGI_FORMAT output_dxgifmt_;
const bool supports_swap_chain_;
};
class MEDIA_GPU_EXPORT CopyTextureSelector : public TextureSelector {
......@@ -68,8 +65,7 @@ class MEDIA_GPU_EXPORT CopyTextureSelector : public TextureSelector {
CopyTextureSelector(VideoPixelFormat pixfmt,
DXGI_FORMAT input_dxgifmt,
DXGI_FORMAT output_dxgifmt,
base::Optional<gfx::ColorSpace> output_color_space,
bool supports_swap_chain);
base::Optional<gfx::ColorSpace> output_color_space);
~CopyTextureSelector() override;
std::unique_ptr<Texture2DWrapper> CreateTextureWrapper(
......
......@@ -1642,25 +1642,27 @@ bool DXVAVideoDecodeAccelerator::SetDecoderInputMediaType() {
RETURN_ON_HR_FAILURE(hr, "Failed to set interlace mode", false);
}
Microsoft::WRL::ComPtr<IMFAttributes> out_attributes;
hr = decoder_->GetOutputStreamAttributes(0, &out_attributes);
RETURN_ON_HR_FAILURE(hr, "Failed to get stream attributes", false);
// On Intel Gen9 and older devices, textures need to be created with a share
// handle or they'll crash in CreateShaderResourceView. crbug.com/1107403
// Technically MF_SA_D3D11_SHARED_WITHOUT_MUTEX is only honored by the sample
// allocator, not by the media foundation transform, but Microsoft's h.264
// transform happens to pass it through.
out_attributes->SetUINT32(MF_SA_D3D11_SHARED_WITHOUT_MUTEX, TRUE);
// These bind flags _must_ be set before SetInputType or SetOutputType to
// ensure that we get the proper surfaces created under the hood.
if (GetPictureBufferMechanism() == PictureBufferMechanism::BIND) {
Microsoft::WRL::ComPtr<IMFAttributes> out_attributes;
HRESULT hr = decoder_->GetOutputStreamAttributes(0, &out_attributes);
RETURN_ON_HR_FAILURE(hr, "Failed to get stream attributes", false);
out_attributes->SetUINT32(MF_SA_D3D11_BINDFLAGS,
D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DECODER);
// TODO(sunnyps): Find if we can always set resource sharing to disabled
if (gl::DirectCompositionSurfaceWin::IsDecodeSwapChainSupported()) {
// Decode swap chains do not support shared resources.
out_attributes->SetUINT32(MF_SA_D3D11_SHARED, FALSE);
} else {
// For some reason newer Intel drivers need D3D11_BIND_DECODER textures to
// be created with a share handle or they'll crash in
// CreateShaderResourceView. Technically MF_SA_D3D11_SHARED_WITHOUT_MUTEX
// is only honored by the sample allocator, not by the media foundation
// transform, but Microsoft's h.264 transform happens to pass it through.
out_attributes->SetUINT32(MF_SA_D3D11_SHARED_WITHOUT_MUTEX, TRUE);
out_attributes->SetUINT32(MF_SA_D3D11_SHARED_WITHOUT_MUTEX, FALSE);
}
}
......
......@@ -39,6 +39,8 @@ bool g_overlay_caps_valid = false;
// Indicates support for either NV12 or YUY2 overlays. GUARDED_BY
// GetOverlayLock().
bool g_supports_overlays = false;
// Whether the DecodeSwapChain is disabled or not.
bool g_decode_swap_chain_disabled = false;
// The lock to guard g_overlay_caps_valid and g_supports_overlays.
base::Lock& GetOverlayLock() {
......@@ -428,7 +430,8 @@ bool DirectCompositionSurfaceWin::AreOverlaysSupported() {
// static
bool DirectCompositionSurfaceWin::IsDecodeSwapChainSupported() {
if (base::FeatureList::IsEnabled(
if (!g_decode_swap_chain_disabled &&
base::FeatureList::IsEnabled(
features::kDirectCompositionUseNV12DecodeSwapChain)) {
UpdateOverlaySupport();
return GetOverlayFormatUsedForSDR() == DXGI_FORMAT_NV12;
......@@ -436,6 +439,11 @@ bool DirectCompositionSurfaceWin::IsDecodeSwapChainSupported() {
return false;
}
// static
void DirectCompositionSurfaceWin::DisableDecodeSwapChain() {
g_decode_swap_chain_disabled = true;
}
// static
void DirectCompositionSurfaceWin::DisableOverlays() {
SetSupportsOverlays(false);
......
......@@ -60,6 +60,7 @@ class GL_EXPORT DirectCompositionSurfaceWin : public GLSurfaceEGL,
// Returns true if zero copy decode swap chain is supported.
static bool IsDecodeSwapChainSupported();
static void DisableDecodeSwapChain();
// After this is called, overlay support is disabled during the
// current GPU process' lifetime.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment