Bug 1497294 - P4. Use EnumSet with D3D11DeviceStatus and checks for P010 and P016 support. r=mattwoodrow

This allows to more easily construct it and add new values as needed.

The other bool members could be made to be part of the set, but this would require more significant code change.

Depends on D8082

Differential Revision: https://phabricator.services.mozilla.com/D8129

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jean-Yves Avenard 2018-10-10 22:14:51 +00:00
parent 81bc2808aa
commit 237243edf2
5 changed files with 115 additions and 41 deletions

View File

@ -11,6 +11,8 @@ using mozilla::gfx::FeatureStatus from "gfxTelemetry.h";
using mozilla::gfx::BackendType from "mozilla/gfx/Types.h";
using mozilla::gfx::IntSize from "mozilla/gfx/Point.h";
using gfxImageFormat from "mozilla/gfx/Types.h";
using mozilla::gfx::D3D11Checks::VideoFormatOption from "mozilla/gfx/D3D11Checks.h";
using mozilla::gfx::D3D11Checks::VideoFormatOptionSet from "mozilla/gfx/D3D11Checks.h";
namespace mozilla {
namespace gfx {
@ -35,7 +37,7 @@ struct D3D11DeviceStatus
uint32_t featureLevel;
DxgiAdapterDesc adapter;
int32_t sequenceNumber;
bool useNV12;
VideoFormatOptionSet formatOptions;
};
struct DevicePrefs

View File

@ -411,33 +411,61 @@ D3D11Checks::DoesRemotePresentWork(IDXGIAdapter* adapter)
return SUCCEEDED(hr) && check;
}
/* static */ bool
D3D11Checks::DoesNV12Work(ID3D11Device* device)
/* static */ D3D11Checks::VideoFormatOptionSet
D3D11Checks::FormatOptions(ID3D11Device* device)
{
if(gfxVars::DXNV12Blocked()) {
return false;
}
auto doesNV12Work = [&]() {
if (gfxVars::DXNV12Blocked()) {
return false;
}
DXGI_ADAPTER_DESC desc;
PodZero(&desc);
if (!GetDxgiDesc(device, &desc)) {
// Failed to retrieve device information, assume it doesn't work
return false;
}
DXGI_ADAPTER_DESC desc;
PodZero(&desc);
if (!GetDxgiDesc(device, &desc)) {
// Failed to retrieve device information, assume it doesn't work
return false;
}
HRESULT hr;
UINT formatSupport;
hr = device->CheckFormatSupport(DXGI_FORMAT_NV12, &formatSupport);
if (FAILED(hr) || !(formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D)) {
return false;
}
UINT formatSupport;
HRESULT hr = device->CheckFormatSupport(DXGI_FORMAT_NV12, &formatSupport);
if (FAILED(hr) || !(formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D)) {
return false;
}
nsString version;
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
if (gfxInfo) {
gfxInfo->GetAdapterDriverVersion(version);
nsString version;
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
if (gfxInfo) {
gfxInfo->GetAdapterDriverVersion(version);
}
return DXVA2Manager::IsNV12Supported(desc.VendorId, desc.DeviceId, version);
};
auto doesP010Work = [&]() {
UINT formatSupport;
HRESULT hr = device->CheckFormatSupport(DXGI_FORMAT_P010, &formatSupport);
return (SUCCEEDED(hr) && (formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D));
};
auto doesP016Work = [&]() {
UINT formatSupport;
HRESULT hr = device->CheckFormatSupport(DXGI_FORMAT_P016, &formatSupport);
return (SUCCEEDED(hr) && (formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D));
};
VideoFormatOptionSet options;
if (!doesNV12Work()) {
// If the device doesn't support NV12, there's really no point testing for
// P010 and P016.
return options;
}
return DXVA2Manager::IsNV12Supported(desc.VendorId, desc.DeviceId, version);
options += VideoFormatOption::NV12;
if (doesP010Work()) {
options += VideoFormatOption::P010;
}
if (doesP016Work()) {
options += VideoFormatOption::P016;
}
return options;
}
} // namespace gfx

View File

@ -6,6 +6,9 @@
#ifndef mozilla_gfx_thebes_D3D11Checks_h
#define mozilla_gfx_thebes_D3D11Checks_h
#include "mozilla/EnumSet.h"
#include "mozilla/EnumTypeTraits.h"
struct ID3D11Device;
struct IDXGIAdapter;
struct DXGI_ADAPTER_DESC;
@ -15,6 +18,14 @@ namespace gfx {
struct D3D11Checks
{
enum class VideoFormatOption
{
NV12,
P010,
P016,
};
using VideoFormatOptionSet = EnumSet<VideoFormatOption>;
static bool DoesRenderTargetViewNeedRecreating(ID3D11Device* aDevice);
static bool DoesDeviceWork();
static bool DoesTextureSharingWork(ID3D11Device* device);
@ -22,10 +33,20 @@ struct D3D11Checks
static void WarnOnAdapterMismatch(ID3D11Device* device);
static bool GetDxgiDesc(ID3D11Device* device, DXGI_ADAPTER_DESC* out);
static bool DoesRemotePresentWork(IDXGIAdapter* adapter);
static bool DoesNV12Work(ID3D11Device* device);
static VideoFormatOptionSet FormatOptions(ID3D11Device* device);
};
} // namespace gfx
// Used for IPDL serialization.
// The 'value' have to be the biggest enum from D3D11Checks::Option.
template <>
struct MaxEnumValue<::mozilla::gfx::D3D11Checks::VideoFormatOption>
{
static constexpr unsigned int value =
static_cast<unsigned int>(gfx::D3D11Checks::VideoFormatOption::P016);
};
} // namespace mozilla
#endif // mozilla_gfx_thebes_D3D11Checks_h

View File

@ -514,19 +514,18 @@ DeviceManagerDx::CreateCompositorDevice(FeatureState& d3d11)
}
uint32_t featureLevel = device->GetFeatureLevel();
bool useNV12 = D3D11Checks::DoesNV12Work(device);
auto formatOptions = D3D11Checks::FormatOptions(device);
{
MutexAutoLock lock(mDeviceLock);
mCompositorDevice = device;
int32_t sequenceNumber = GetNextDeviceCounter();
mDeviceStatus = Some(D3D11DeviceStatus(
false,
textureSharingWorks,
featureLevel,
DxgiAdapterDesc::From(desc),
sequenceNumber,
useNV12));
mDeviceStatus = Some(D3D11DeviceStatus(false,
textureSharingWorks,
featureLevel,
DxgiAdapterDesc::From(desc),
sequenceNumber,
formatOptions));
}
mCompositorDevice->SetExceptionMode(0);
}
@ -623,19 +622,18 @@ DeviceManagerDx::CreateWARPCompositorDevice()
int featureLevel = device->GetFeatureLevel();
bool useNV12 = D3D11Checks::DoesNV12Work(device);
auto formatOptions = D3D11Checks::FormatOptions(device);
{
MutexAutoLock lock(mDeviceLock);
mCompositorDevice = device;
int32_t sequenceNumber = GetNextDeviceCounter();
mDeviceStatus = Some(D3D11DeviceStatus(
true,
textureSharingWorks,
featureLevel,
nullAdapter,
sequenceNumber,
useNV12));
mDeviceStatus = Some(D3D11DeviceStatus(true,
textureSharingWorks,
featureLevel,
nullAdapter,
sequenceNumber,
formatOptions));
}
mCompositorDevice->SetExceptionMode(0);
@ -1179,7 +1177,30 @@ DeviceManagerDx::CanUseNV12()
if (!mDeviceStatus) {
return false;
}
return mDeviceStatus->useNV12();
return mDeviceStatus->formatOptions().contains(
D3D11Checks::VideoFormatOption::NV12);
}
bool
DeviceManagerDx::CanUseP010()
{
MutexAutoLock lock(mDeviceLock);
if (!mDeviceStatus) {
return false;
}
return mDeviceStatus->formatOptions().contains(
D3D11Checks::VideoFormatOption::P010);
}
bool
DeviceManagerDx::CanUseP016()
{
MutexAutoLock lock(mDeviceLock);
if (!mDeviceStatus) {
return false;
}
return mDeviceStatus->formatOptions().contains(
D3D11Checks::VideoFormatOption::P016);
}
bool

View File

@ -69,6 +69,8 @@ public:
bool TextureSharingWorks();
bool IsWARP();
bool CanUseNV12();
bool CanUseP010();
bool CanUseP016();
bool CanUseDComp();
// Returns true if we can create a texture with