Flutter Engine
The Flutter Engine
GraphiteDawnTestContext.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2022 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
18
19#include "dawn/dawn_proc.h"
20
21#define LOG_ADAPTER 0
22
23namespace skiatest::graphite {
24
25// TODO: http://crbug.com/dawn/2450 - Currently manually setting the device to null and calling
26// tick/process events one last time to ensure that the device is lost accordingly at
27// destruction. Once device lost is, by default, a spontaneous event, remove this.
29 fBackendContext.fDevice = nullptr;
30 tick();
31}
32
33std::unique_ptr<GraphiteTestContext> DawnTestContext::Make(wgpu::BackendType backend) {
34 static std::unique_ptr<dawn::native::Instance> sInstance;
35 static SkOnce sOnce;
36
37 static constexpr const char* kToggles[] = {
38 "allow_unsafe_apis", // Needed for dual-source blending.
39 "use_user_defined_labels_in_backend",
40 };
41 wgpu::DawnTogglesDescriptor togglesDesc;
42 togglesDesc.enabledToggleCount = std::size(kToggles);
43 togglesDesc.enabledToggles = kToggles;
44
45 // Creation of Instance is cheap but calling EnumerateAdapters can be expensive the first time,
46 // but then the results are cached on the Instance object. So save the Instance here so we can
47 // avoid the overhead of EnumerateAdapters on every test.
48 sOnce([&]{
49 DawnProcTable backendProcs = dawn::native::GetProcs();
50 dawnProcSetProcs(&backendProcs);
51 WGPUInstanceDescriptor desc{};
52 // need for WaitAny with timeout > 0
53 desc.features.timedWaitAnyEnable = true;
54 sInstance = std::make_unique<dawn::native::Instance>(&desc);
55 });
56
57 dawn::native::Adapter matchedAdaptor;
58
59 wgpu::RequestAdapterOptions options;
60 options.nextInChain = &togglesDesc;
61 std::vector<dawn::native::Adapter> adapters = sInstance->EnumerateAdapters(&options);
62 SkASSERT(!adapters.empty());
63 // Sort adapters by adapterType(DiscreteGPU, IntegratedGPU, CPU) and
64 // backendType(WebGPU, D3D11, D3D12, Metal, Vulkan, OpenGL, OpenGLES).
66 adapters.begin(), adapters.end(), [](dawn::native::Adapter a, dawn::native::Adapter b) {
67 wgpu::AdapterInfo infoA;
68 wgpu::AdapterInfo infoB;
69 a.GetInfo(&infoA);
70 b.GetInfo(&infoB);
71 return std::tuple(infoA.adapterType, infoA.backendType) <
72 std::tuple(infoB.adapterType, infoB.backendType);
73 });
74
75 for (const auto& adapter : adapters) {
76 wgpu::AdapterInfo props;
77 adapter.GetInfo(&props);
78 if (backend == props.backendType) {
79 matchedAdaptor = adapter;
80 break;
81 }
82 }
83
84 if (!matchedAdaptor) {
85 return nullptr;
86 }
87
88#if LOG_ADAPTER
89 wgpu::AdapterInfo info;
90 sAdapter.GetInfo(&info);
91 SkDebugf("GPU: %s\nDriver: %s\n", info.device, info.description);
92#endif
93
94 std::vector<wgpu::FeatureName> features;
95 wgpu::Adapter adapter = matchedAdaptor.Get();
96 if (adapter.HasFeature(wgpu::FeatureName::MSAARenderToSingleSampled)) {
97 features.push_back(wgpu::FeatureName::MSAARenderToSingleSampled);
98 }
99 if (adapter.HasFeature(wgpu::FeatureName::TransientAttachments)) {
100 features.push_back(wgpu::FeatureName::TransientAttachments);
101 }
102 if (adapter.HasFeature(wgpu::FeatureName::Unorm16TextureFormats)) {
103 features.push_back(wgpu::FeatureName::Unorm16TextureFormats);
104 }
105 if (adapter.HasFeature(wgpu::FeatureName::DualSourceBlending)) {
106 features.push_back(wgpu::FeatureName::DualSourceBlending);
107 }
108 if (adapter.HasFeature(wgpu::FeatureName::FramebufferFetch)) {
109 features.push_back(wgpu::FeatureName::FramebufferFetch);
110 }
111 if (adapter.HasFeature(wgpu::FeatureName::BufferMapExtendedUsages)) {
112 features.push_back(wgpu::FeatureName::BufferMapExtendedUsages);
113 }
114 if (adapter.HasFeature(wgpu::FeatureName::TextureCompressionETC2)) {
115 features.push_back(wgpu::FeatureName::TextureCompressionETC2);
116 }
117 if (adapter.HasFeature(wgpu::FeatureName::TextureCompressionBC)) {
118 features.push_back(wgpu::FeatureName::TextureCompressionBC);
119 }
120 if (adapter.HasFeature(wgpu::FeatureName::R8UnormStorage)) {
121 features.push_back(wgpu::FeatureName::R8UnormStorage);
122 }
123 if (adapter.HasFeature(wgpu::FeatureName::DawnLoadResolveTexture)) {
124 features.push_back(wgpu::FeatureName::DawnLoadResolveTexture);
125 }
126
127 wgpu::DeviceDescriptor desc;
128 desc.requiredFeatureCount = features.size();
129 desc.requiredFeatures = features.data();
130 desc.nextInChain = &togglesDesc;
131 desc.deviceLostCallbackInfo.callback =
132 [](WGPUDeviceImpl *const *, WGPUDeviceLostReason reason, const char* message, void*) {
133 if (reason != WGPUDeviceLostReason_Destroyed) {
134 SK_ABORT("Device lost: %s\n", message);
135 }
136 };
137
138 wgpu::Device device = wgpu::Device::Acquire(matchedAdaptor.CreateDevice(&desc));
140 device.SetUncapturedErrorCallback(
141 [](WGPUErrorType type, const char* message, void*) {
142 SkDebugf("Device error: %s\n", message);
143 },
144 /*userdata=*/nullptr);
145
147 backendContext.fInstance = wgpu::Instance(sInstance->Get());
148 backendContext.fDevice = device;
149 backendContext.fQueue = device.GetQueue();
150 return std::unique_ptr<GraphiteTestContext>(new DawnTestContext(backendContext));
151}
152
154 wgpu::AdapterInfo info;
155 fBackendContext.fDevice.GetAdapter().GetInfo(&info);
156 switch (info.backendType) {
157 case wgpu::BackendType::D3D11:
159
160 case wgpu::BackendType::D3D12:
162
163 case wgpu::BackendType::Metal:
165
166 case wgpu::BackendType::Vulkan:
168
169 case wgpu::BackendType::OpenGL:
171
172 case wgpu::BackendType::OpenGLES:
174 default:
175 SK_ABORT("unexpected Dawn backend");
177 }
178}
179
180std::unique_ptr<skgpu::graphite::Context> DawnTestContext::makeContext(const TestOptions& options) {
181 skgpu::graphite::ContextOptions revisedContextOptions(options.fContextOptions);
182 skgpu::graphite::ContextOptionsPriv contextOptionsPriv;
183 if (!options.fContextOptions.fOptionsPriv) {
184 revisedContextOptions.fOptionsPriv = &contextOptionsPriv;
185 }
186 // Needed to make synchronous readPixels work
187 revisedContextOptions.fOptionsPriv->fStoreContextRefInRecorder = true;
188
189 auto backendContext = fBackendContext;
190 if (options.fNeverYieldToWebGPU) {
191 backendContext.fTick = nullptr;
192 }
193
194 return skgpu::graphite::ContextFactory::MakeDawn(backendContext, revisedContextOptions);
195}
196
198
199} // namespace skiatest::graphite
const char * options
const char * backend
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
#define SkASSERT(cond)
Definition: SkAssert.h:116
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static std::vector< SkPDFIndirectReference > sort(const THashSet< SkPDFIndirectReference > &src)
GLenum type
Definition: SkOnce.h:22
skgpu::graphite::DawnBackendContext fBackendContext
static std::unique_ptr< GraphiteTestContext > Make(wgpu::BackendType backend)
skgpu::ContextType contextType() override
skgpu::BackendApi backend() override
DawnTestContext(const skgpu::graphite::DawnBackendContext &backendContext)
std::unique_ptr< skgpu::graphite::Context > makeContext(const TestOptions &) override
VkDevice device
Definition: main.cc:53
static bool b
struct MyStruct a[10]
Win32Message message
DlSurfaceProvider::BackendType BackendType
Definition: dl_benchmarks.h:33
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
SK_API std::unique_ptr< Context > MakeDawn(const DawnBackendContext &, const ContextOptions &)
ContextType
Definition: ContextType.h:19
@ kDawn_OpenGLES
Dawn on OpenGL.
@ kDawn_Metal
Dawn on Direct3D12.
@ kDawn_D3D12
Dawn on Direct3D11.
@ kDawn_Vulkan
Dawn on Metal.
@ kDawn_OpenGL
Dawn on Vulkan.
@ kDawn_D3D11
Direct3D 12.
@ kMock
Dawn on OpenGL ES.
ContextOptionsPriv * fOptionsPriv