0

Fix Graphite on D3D12 startup issues

Recent SharedImage changes always assumed the presence of a D3D11
device. When graphite runs with D3D12, no D3D11 device was provided
to the D3DImageBackingFactory constructor, causing it to crash
At the same time, since InitializeDirectComposition is always called
with ANGLE's D3D11 device, it incorrectly, returned true for
IsD3DSharedImageSupported and crashed when the renderer process sent
it scanout images.

The CL rearranges GPU initialization such that DirectComposition is
initialized after the Dawn context provider, thus providing it the
correct D3D11 device, or no D3D11 device if there is none.
IsD3DSharedImageSupport is provided with the SharedContextState so it
can learn the truth about there being no D3D11 device.

With these changes, D3DSharedImageFactory is never created and no
scanout images are requested from the renderer process. Graphite on
D3D12 boots and is able to draw basic web pages.

Future CLs will slowly bring back SharedImage capability when Graphite
runs on D3D12.

Bug: 396312708
Change-Id: I30860ecd523eb158e57b2c65f9be4d6ce246fbcc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6288547
Reviewed-by: Sunny Sachanandani <sunnyps@chromium.org>
Commit-Queue: Rafael Cintron <rafael.cintron@microsoft.com>
Cr-Commit-Position: refs/heads/main@{#1423478}
This commit is contained in:
Rafael Cintron
2025-02-21 16:21:44 -08:00
committed by Chromium LUCI CQ
parent 275044ecef
commit f47b7b4c7a
10 changed files with 55 additions and 20 deletions

@ -523,11 +523,6 @@ void GpuServiceImpl::UpdateGPUInfo() {
image_decode_accelerator_worker_->GetSupportedProfiles();
}
#if BUILDFLAG(IS_WIN)
gpu_info_.shared_image_d3d =
gpu::D3DImageBackingFactory::IsD3DSharedImageSupported(gpu_preferences_);
#endif
// Record initialization only after collecting the GPU info because that can
// take a significant amount of time.
base::TimeTicks now = base::TimeTicks::Now();
@ -592,6 +587,15 @@ void GpuServiceImpl::InitializeWithHost(
std::move(pending_gpu_host), std::move(use_shader_cache_shm_count),
default_offscreen_surface, std::move(creation_params), sync_point_manager,
shared_image_manager, scheduler, shutdown_event);
#if BUILDFLAG(IS_WIN)
// shared_image_d3d must be initialized after we call
// InitializeWithHostInternal as that is where the shared context state is
// created.
gpu_info_.shared_image_d3d =
gpu::D3DImageBackingFactory::IsD3DSharedImageSupported(
GetContextState()->GetD3D11Device().Get(), gpu_preferences_);
#endif
}
#else
void GpuServiceImpl::InitializeWithHost(

@ -220,14 +220,16 @@ D3DImageBackingFactory::SwapChainBackings::operator=(
// static
bool D3DImageBackingFactory::IsD3DSharedImageSupported(
ID3D11Device* d3d11_device,
const GpuPreferences& gpu_preferences) {
// Only supported for passthrough command decoder.
if (!gpu_preferences.use_passthrough_cmd_decoder) {
return false;
}
// D3D11 device will be null if ANGLE is using the D3D9 backend.
if (!gl::QueryD3D11DeviceObjectFromANGLE()) {
// D3D11 device will be null if ANGLE is using the D3D9 backend or
// when we're running with Graphite on D3D12.
if (!d3d11_device) {
return false;
}

@ -48,7 +48,8 @@ class GPU_GLES2_EXPORT D3DImageBackingFactory
// Returns true if D3D shared images are supported and this factory should be
// used. Generally this means Skia-GL, passthrough decoder, and ANGLE-D3D11.
static bool IsD3DSharedImageSupported(const GpuPreferences& gpu_preferences);
static bool IsD3DSharedImageSupported(ID3D11Device* d3d11_device,
const GpuPreferences& gpu_preferences);
// Returns true if DXGI swap chain shared images for overlays are supported.
static bool IsSwapChainSupported(const GpuPreferences& gpu_preferences);

@ -78,6 +78,7 @@ class DCompImageBackingFactoryTest : public testing::Test {
context_state_->InitializeGL(GpuPreferences(), std::move(feature_info));
d3d11_device_ = gl::QueryD3D11DeviceObjectFromANGLE();
gl::InitializeDirectComposition(d3d11_device_);
memory_type_tracker_ = std::make_unique<MemoryTypeTracker>(nullptr);
shared_image_representation_factory_ =
@ -421,11 +422,11 @@ class DCompImageBackingFactoryVisualTreeTest
protected:
DCompImageBackingFactoryVisualTreeTest()
: window_size_(100, 100),
window_(&platform_delegate_, gfx::Rect(window_size_)),
dcomp_device_(gl::GetDirectCompositionDevice()) {}
window_(&platform_delegate_, gfx::Rect(window_size_)) {}
void SetUp() override {
DCompImageBackingFactoryTest::SetUp();
dcomp_device_ = gl::GetDirectCompositionDevice();
static_cast<ui::PlatformWindow*>(&window_)->Show();
child_window_.Initialize();

@ -240,7 +240,7 @@ SharedImageFactory::SharedImageFactory(
factories_.push_back(
std::make_unique<DCompImageBackingFactory>(context_state_));
}
if (D3DImageBackingFactory::IsD3DSharedImageSupported(gpu_preferences_)) {
if (IsD3DSharedImageSupported()) {
auto d3d_factory = std::make_unique<D3DImageBackingFactory>(
context_state_->GetD3D11Device(),
shared_image_manager_->dxgi_shared_handle_manager(),
@ -641,6 +641,15 @@ void SharedImageFactory::DestroyAllSharedImages(bool have_context) {
}
#if BUILDFLAG(IS_WIN)
bool SharedImageFactory::IsD3DSharedImageSupported() const {
if (!context_state_) {
return false;
}
return D3DImageBackingFactory::IsD3DSharedImageSupported(
context_state_->GetD3D11Device().Get(), gpu_preferences_);
}
bool SharedImageFactory::CreateSwapChain(const Mailbox& front_buffer_mailbox,
const Mailbox& back_buffer_mailbox,
viz::SharedImageFormat format,
@ -806,8 +815,7 @@ gpu::SharedImageCapabilities SharedImageFactory::MakeCapabilities() {
#endif
#if BUILDFLAG(IS_WIN)
shared_image_caps.shared_image_d3d =
D3DImageBackingFactory::IsD3DSharedImageSupported(gpu_preferences_);
shared_image_caps.shared_image_d3d = IsD3DSharedImageSupported();
shared_image_caps.shared_image_swap_chain =
shared_image_caps.shared_image_d3d &&
D3DImageBackingFactory::IsSwapChainSupported(gpu_preferences_);

@ -171,6 +171,9 @@ class GPU_GLES2_EXPORT SharedImageFactory {
const std::string& debug_label);
bool IsNativeBufferSupported(gfx::BufferFormat format,
gfx::BufferUsage usage);
#if BUILDFLAG(IS_WIN)
bool IsD3DSharedImageSupported() const;
#endif
raw_ptr<SharedImageManager> shared_image_manager_;
const scoped_refptr<SharedContextState> context_state_;

@ -64,6 +64,7 @@
#if BUILDFLAG(IS_WIN)
#include "gpu/config/gpu_driver_bug_workarounds.h"
#include "ui/gl/direct_composition_support.h"
#include "ui/gl/gl_angle_util_win.h"
#include "ui/gl/gl_surface_egl.h"
#endif
@ -757,8 +758,6 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line,
->GetSupportedFormatsForGLNativePixmapImport();
#endif // BUILDFLAG(IS_OZONE)
InitializePlatformOverlaySettings(&gpu_info_, gpu_feature_info_);
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
// Driver may create a compatibility profile context when collect graphics
// information on Linux platform. Try to collect graphics information
@ -876,6 +875,20 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line,
}
}
#if BUILDFLAG(IS_WIN)
{
Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device;
if (dawn_context_provider_) {
d3d11_device = dawn_context_provider_->GetD3D11Device();
} else {
d3d11_device = gl::QueryD3D11DeviceObjectFromANGLE();
}
gl::InitializeDirectComposition(std::move(d3d11_device));
}
#endif
InitializePlatformOverlaySettings(&gpu_info_, gpu_feature_info_);
init_successful_ = true;
SetSkiaBackendType();
#if BUILDFLAG(IS_OZONE)

@ -244,6 +244,9 @@ class DCompPresenterTestBase : public testing::Test {
base::PowerStateObserver::BatteryPowerStatus::kBatteryPower);
// All bots run on non-blocklisted hardware that supports DComp (>Win7)
Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device =
QueryD3D11DeviceObjectFromANGLE();
InitializeDirectComposition(d3d11_device.Get());
ASSERT_TRUE(DirectCompositionSupported());
presenter_ = CreateDCompPresenter();

@ -664,7 +664,11 @@ HRESULT DCompositionGetStatistics(COMPOSITION_FRAME_ID frameId,
void InitializeDirectComposition(
Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device) {
DCHECK(!g_dcomp_device);
CHECK(!g_dcomp_device);
if (!d3d11_device) {
return;
}
if (GetGlWorkarounds().disable_direct_composition) {
return;
}

@ -17,7 +17,6 @@
#include "base/trace_event/trace_event.h"
#include "base/win/windows_version.h"
#include "ui/gl/direct_composition_support.h"
#include "ui/gl/gl_angle_util_win.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_display.h"
#include "ui/gl/gl_egl_api_implementation.h"
@ -146,9 +145,6 @@ GLDisplay* InitializeGLOneOffPlatform(gl::GpuPreference gpu_preference) {
LOG(ERROR) << "GLDisplayEGL::Initialize failed.";
return nullptr;
}
if (auto d3d11_device = QueryD3D11DeviceObjectFromANGLE()) {
InitializeDirectComposition(std::move(d3d11_device));
}
break;
}
case kGLImplementationMockGL: