Commit 086515eb authored by Ted Meyer's avatar Ted Meyer Committed by Commit Bot

Moved GetMaxResolutionsForGUIDs and the GUID search code

Splitting up the CL for D3D11 reporting max resolutions

Change-Id: I974fd24d49ce086398caf3bec0a7daa92eff8e6d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1696177
Commit-Queue: Ted Meyer <tmathmeyer@chromium.org>
Reviewed-by: default avatarFrank Liberato <liberato@chromium.org>
Cr-Commit-Position: refs/heads/master@{#676214}
parent 63e1360c
...@@ -134,60 +134,6 @@ uint64_t GetCurrentQPC() { ...@@ -134,60 +134,6 @@ uint64_t GetCurrentQPC() {
uint64_t g_last_process_output_time; uint64_t g_last_process_output_time;
HRESULT g_last_device_removed_reason; HRESULT g_last_device_removed_reason;
// Returns a tuple of (LandscapeMax, PortraitMax). If landscape maximum can not
// be computed, the value of |default_max| is returned for the landscape maximum
// and a zero size value is returned for portrait max (erring conservatively).
using ResolutionPair = std::pair<gfx::Size, gfx::Size>;
ResolutionPair GetMaxResolutionsForGUIDs(
const gfx::Size& default_max,
ID3D11VideoDevice* video_device,
const std::vector<GUID>& valid_guids,
const std::vector<gfx::Size>& resolutions_to_test,
DXGI_FORMAT format = DXGI_FORMAT_NV12) {
TRACE_EVENT0("gpu,startup", "GetMaxResolutionsForGUIDs");
ResolutionPair result(default_max, gfx::Size());
// Enumerate supported video profiles and look for the profile.
GUID decoder_guid = GUID_NULL;
UINT profile_count = video_device->GetVideoDecoderProfileCount();
for (UINT profile_idx = 0; profile_idx < profile_count; profile_idx++) {
GUID profile_id = {};
if (SUCCEEDED(
video_device->GetVideoDecoderProfile(profile_idx, &profile_id)) &&
std::find(valid_guids.begin(), valid_guids.end(), profile_id) !=
valid_guids.end()) {
decoder_guid = profile_id;
break;
}
}
if (decoder_guid == GUID_NULL)
return result;
// Verify input is in ascending order by height.
DCHECK(std::is_sorted(resolutions_to_test.begin(), resolutions_to_test.end(),
[](const gfx::Size& a, const gfx::Size& b) {
return a.height() < b.height();
}));
for (const auto& res : resolutions_to_test) {
if (!media::IsResolutionSupportedForDevice(res, decoder_guid, video_device,
format)) {
break;
}
result.first = res;
}
// The max supported portrait resolution should be just be a w/h flip of the
// max supported landscape resolution.
gfx::Size flipped(result.first.height(), result.first.width());
if (media::IsResolutionSupportedForDevice(flipped, decoder_guid, video_device,
format)) {
result.second = flipped;
}
return result;
}
} // namespace } // namespace
namespace media { namespace media {
...@@ -1290,45 +1236,10 @@ DXVAVideoDecodeAccelerator::GetSupportedProfiles( ...@@ -1290,45 +1236,10 @@ DXVAVideoDecodeAccelerator::GetSupportedProfiles(
ResolutionPair max_vp9_profile0_resolutions; ResolutionPair max_vp9_profile0_resolutions;
ResolutionPair max_vp9_profile2_resolutions; ResolutionPair max_vp9_profile2_resolutions;
if (base::win::GetVersion() > base::win::Version::WIN7) { GetResolutionsForDecoders(
// To detect if a driver supports the desired resolutions, we try and create {DXVA2_ModeH264_E, DXVA2_Intel_ModeH264_E},
// a DXVA decoder instance for that resolution and profile. If that succeeds gl::QueryD3D11DeviceObjectFromANGLE(), workarounds, &max_h264_resolutions,
// we assume that the driver supports decoding for that resolution. &max_vp9_profile0_resolutions, &max_vp9_profile2_resolutions);
ComD3D11Device device = gl::QueryD3D11DeviceObjectFromANGLE();
// Legacy AMD drivers with UVD3 or earlier and some Intel GPU's crash while
// creating surfaces larger than 1920 x 1088.
if (device && !IsLegacyGPU(device.Get())) {
ComD3D11VideoDevice video_device;
if (SUCCEEDED(device.As(&video_device))) {
max_h264_resolutions = GetMaxResolutionsForGUIDs(
max_h264_resolutions.first, video_device.Get(),
{DXVA2_ModeH264_E, DXVA2_Intel_ModeH264_E},
{gfx::Size(2560, 1440), gfx::Size(3840, 2160),
gfx::Size(4096, 2160), gfx::Size(4096, 2304)});
if (!workarounds.disable_accelerated_vpx_decode) {
max_vp9_profile0_resolutions = GetMaxResolutionsForGUIDs(
max_vp9_profile0_resolutions.first, video_device.Get(),
{D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0},
{gfx::Size(4096, 2160), gfx::Size(4096, 2304),
gfx::Size(7680, 4320), gfx::Size(8192, 4320),
gfx::Size(8192, 8192)});
// RS3 has issues with VP9.2 decoding. See https://crbug.com/937108.
if (base::win::GetVersion() != base::win::Version::WIN10_RS3) {
max_vp9_profile2_resolutions = GetMaxResolutionsForGUIDs(
max_vp9_profile2_resolutions.first, video_device.Get(),
{D3D11_DECODER_PROFILE_VP9_VLD_10BIT_PROFILE2},
{gfx::Size(4096, 2160), gfx::Size(4096, 2304),
gfx::Size(7680, 4320), gfx::Size(8192, 4320),
gfx::Size(8192, 8192)},
DXGI_FORMAT_P010);
}
}
}
}
}
for (const auto& supported_profile : kSupportedProfiles) { for (const auto& supported_profile : kSupportedProfiles) {
const bool is_h264 = supported_profile >= H264PROFILE_MIN && const bool is_h264 = supported_profile >= H264PROFILE_MIN &&
......
...@@ -155,4 +155,101 @@ bool IsResolutionSupportedForDevice(const gfx::Size& resolution_to_test, ...@@ -155,4 +155,101 @@ bool IsResolutionSupportedForDevice(const gfx::Size& resolution_to_test,
config_count > 0; config_count > 0;
} }
// Returns a tuple of (LandscapeMax, PortraitMax). If landscape maximum can not
// be computed, the value of |default_max| is returned for the landscape maximum
// and a zero size value is returned for portrait max (erring conservatively).
ResolutionPair GetMaxResolutionsForGUIDs(
const gfx::Size& default_max,
ID3D11VideoDevice* video_device,
const std::vector<GUID>& valid_guids,
const std::vector<gfx::Size>& resolutions_to_test,
DXGI_FORMAT format) {
TRACE_EVENT0("gpu,startup", "GetMaxResolutionsForGUIDs");
ResolutionPair result(default_max, gfx::Size());
// Enumerate supported video profiles and look for the profile.
GUID decoder_guid = GUID_NULL;
UINT profile_count = video_device->GetVideoDecoderProfileCount();
for (UINT profile_idx = 0; profile_idx < profile_count; profile_idx++) {
GUID profile_id = {};
if (SUCCEEDED(
video_device->GetVideoDecoderProfile(profile_idx, &profile_id)) &&
std::find(valid_guids.begin(), valid_guids.end(), profile_id) !=
valid_guids.end()) {
decoder_guid = profile_id;
break;
}
}
if (decoder_guid == GUID_NULL)
return result;
// Verify input is in ascending order by height.
DCHECK(std::is_sorted(resolutions_to_test.begin(), resolutions_to_test.end(),
[](const gfx::Size& a, const gfx::Size& b) {
return a.height() < b.height();
}));
for (const auto& res : resolutions_to_test) {
if (!media::IsResolutionSupportedForDevice(res, decoder_guid, video_device,
format)) {
break;
}
result.first = res;
}
// The max supported portrait resolution should be just be a w/h flip of the
// max supported landscape resolution.
gfx::Size flipped(result.first.height(), result.first.width());
if (media::IsResolutionSupportedForDevice(flipped, decoder_guid, video_device,
format)) {
result.second = flipped;
}
return result;
}
void GetResolutionsForDecoders(std::vector<GUID> h264_guids,
ComD3D11Device device,
const gpu::GpuDriverBugWorkarounds& workarounds,
ResolutionPair* h264_resolutions,
ResolutionPair* vp9_0_resolutions,
ResolutionPair* vp9_2_resolutions) {
if (base::win::GetVersion() > base::win::Version::WIN7) {
// To detect if a driver supports the desired resolutions, we try and create
// a DXVA decoder instance for that resolution and profile. If that succeeds
// we assume that the driver supports decoding for that resolution.
// Legacy AMD drivers with UVD3 or earlier and some Intel GPU's crash while
// creating surfaces larger than 1920 x 1088.
if (device && !IsLegacyGPU(device.Get())) {
ComD3D11VideoDevice video_device;
if (SUCCEEDED(device.As(&video_device))) {
*h264_resolutions = GetMaxResolutionsForGUIDs(
h264_resolutions->first, video_device.Get(), h264_guids,
{gfx::Size(2560, 1440), gfx::Size(3840, 2160),
gfx::Size(4096, 2160), gfx::Size(4096, 2304)});
if (!workarounds.disable_accelerated_vpx_decode) {
*vp9_0_resolutions = GetMaxResolutionsForGUIDs(
vp9_0_resolutions->first, video_device.Get(),
{D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0},
{gfx::Size(4096, 2160), gfx::Size(4096, 2304),
gfx::Size(7680, 4320), gfx::Size(8192, 4320),
gfx::Size(8192, 8192)});
// RS3 has issues with VP9.2 decoding. See https://crbug.com/937108.
if (base::win::GetVersion() != base::win::Version::WIN10_RS3) {
*vp9_2_resolutions = GetMaxResolutionsForGUIDs(
vp9_2_resolutions->first, video_device.Get(),
{D3D11_DECODER_PROFILE_VP9_VLD_10BIT_PROFILE2},
{gfx::Size(4096, 2160), gfx::Size(4096, 2304),
gfx::Size(7680, 4320), gfx::Size(8192, 4320),
gfx::Size(8192, 8192)},
DXGI_FORMAT_P010);
}
}
}
}
}
}
} // namespace media } // namespace media
...@@ -7,11 +7,18 @@ ...@@ -7,11 +7,18 @@
#include <d3d11_1.h> #include <d3d11_1.h>
#include <wrl/client.h> #include <wrl/client.h>
#include <memory>
#include <utility>
#include <vector>
#include "gpu/config/gpu_driver_bug_workarounds.h"
#include "media/gpu/windows/d3d11_com_defs.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
namespace media { namespace media {
using ResolutionPair = std::pair<gfx::Size, gfx::Size>;
bool IsLegacyGPU(ID3D11Device* device); bool IsLegacyGPU(ID3D11Device* device);
// Returns true if a ID3D11VideoDecoder can be created for |resolution_to_test| // Returns true if a ID3D11VideoDecoder can be created for |resolution_to_test|
...@@ -21,6 +28,20 @@ bool IsResolutionSupportedForDevice(const gfx::Size& resolution_to_test, ...@@ -21,6 +28,20 @@ bool IsResolutionSupportedForDevice(const gfx::Size& resolution_to_test,
ID3D11VideoDevice* video_device, ID3D11VideoDevice* video_device,
DXGI_FORMAT format); DXGI_FORMAT format);
ResolutionPair GetMaxResolutionsForGUIDs(
const gfx::Size& default_max,
ID3D11VideoDevice* video_device,
const std::vector<GUID>& valid_guids,
const std::vector<gfx::Size>& resolutions_to_test,
DXGI_FORMAT format = DXGI_FORMAT_NV12);
void GetResolutionsForDecoders(std::vector<GUID> h264_guids,
ComD3D11Device device,
const gpu::GpuDriverBugWorkarounds& workarounds,
ResolutionPair* h264_resolutions,
ResolutionPair* vp9_0_resolutions,
ResolutionPair* vp9_2_resolutions);
} // namespace media } // namespace media
#endif // MEDIA_GPU_WINDOWS_SUPPORTED_PROFILE_HELPERS_H_ #endif // MEDIA_GPU_WINDOWS_SUPPORTED_PROFILE_HELPERS_H_
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