@@ -107,8 +107,8 @@ uint64_t CalculateHash(void* ptr) {
107
107
ContextVK::ContextVK () : hash_(CalculateHash(this )) {}
108
108
109
109
ContextVK::~ContextVK () {
110
- if (device_ ) {
111
- [[maybe_unused]] auto result = device_ ->waitIdle ();
110
+ if (device_holder_-> device ) {
111
+ [[maybe_unused]] auto result = device_holder_-> device ->waitIdle ();
112
112
}
113
113
CommandPoolVK::ClearAllPools (this );
114
114
}
@@ -191,14 +191,17 @@ void ContextVK::Setup(Settings settings) {
191
191
instance_info.setPApplicationInfo (&application_info);
192
192
instance_info.setFlags (instance_flags);
193
193
194
- auto instance = vk::createInstanceUnique (instance_info);
195
- if (instance.result != vk::Result::eSuccess) {
196
- VALIDATION_LOG << " Could not create Vulkan instance: "
197
- << vk::to_string (instance.result );
198
- return ;
194
+ auto device_holder = std::make_shared<UniqueDeviceHolder>();
195
+ {
196
+ auto instance = vk::createInstanceUnique (instance_info);
197
+ if (instance.result != vk::Result::eSuccess) {
198
+ VALIDATION_LOG << " Could not create Vulkan instance: "
199
+ << vk::to_string (instance.result );
200
+ return ;
201
+ }
202
+ device_holder->instance = std::move (instance.value );
199
203
}
200
-
201
- dispatcher.init (instance.value .get ());
204
+ dispatcher.init (device_holder->instance .get ());
202
205
203
206
// ----------------------------------------------------------------------------
204
207
// / Setup the debug report.
@@ -207,7 +210,7 @@ void ContextVK::Setup(Settings settings) {
207
210
// / initialization issues.
208
211
// /
209
212
auto debug_report =
210
- std::make_unique<DebugReportVK>(*caps, instance. value .get ());
213
+ std::make_unique<DebugReportVK>(*caps, device_holder-> instance .get ());
211
214
212
215
if (!debug_report->IsValid ()) {
213
216
VALIDATION_LOG << " Could not setup debug report." ;
@@ -217,21 +220,25 @@ void ContextVK::Setup(Settings settings) {
217
220
// ----------------------------------------------------------------------------
218
221
// / Pick the physical device.
219
222
// /
220
- auto physical_device = PickPhysicalDevice (*caps, instance.value .get ());
221
- if (!physical_device.has_value ()) {
222
- VALIDATION_LOG << " No valid Vulkan device found." ;
223
- return ;
223
+ {
224
+ auto physical_device =
225
+ PickPhysicalDevice (*caps, device_holder->instance .get ());
226
+ if (!physical_device.has_value ()) {
227
+ VALIDATION_LOG << " No valid Vulkan device found." ;
228
+ return ;
229
+ }
230
+ device_holder->physical_device = std::move (physical_device.value ());
224
231
}
225
232
226
233
// ----------------------------------------------------------------------------
227
234
// / Pick device queues.
228
235
// /
229
236
auto graphics_queue =
230
- PickQueue (physical_device. value () , vk::QueueFlagBits::eGraphics);
237
+ PickQueue (device_holder-> physical_device , vk::QueueFlagBits::eGraphics);
231
238
auto transfer_queue =
232
- PickQueue (physical_device. value () , vk::QueueFlagBits::eTransfer);
239
+ PickQueue (device_holder-> physical_device , vk::QueueFlagBits::eTransfer);
233
240
auto compute_queue =
234
- PickQueue (physical_device. value () , vk::QueueFlagBits::eCompute);
241
+ PickQueue (device_holder-> physical_device , vk::QueueFlagBits::eCompute);
235
242
236
243
if (!graphics_queue.has_value ()) {
237
244
VALIDATION_LOG << " Could not pick graphics queue." ;
@@ -250,7 +257,7 @@ void ContextVK::Setup(Settings settings) {
250
257
// / Create the logical device.
251
258
// /
252
259
auto enabled_device_extensions =
253
- caps->GetRequiredDeviceExtensions (physical_device. value () );
260
+ caps->GetRequiredDeviceExtensions (device_holder-> physical_device );
254
261
if (!enabled_device_extensions.has_value ()) {
255
262
// This shouldn't happen since we already did device selection. But doesn't
256
263
// hurt to check again.
@@ -266,7 +273,7 @@ void ContextVK::Setup(Settings settings) {
266
273
{graphics_queue.value (), compute_queue.value (), transfer_queue.value ()});
267
274
268
275
const auto required_features =
269
- caps->GetRequiredDeviceFeatures (physical_device. value () );
276
+ caps->GetRequiredDeviceFeatures (device_holder-> physical_device );
270
277
if (!required_features.has_value ()) {
271
278
// This shouldn't happen since the device can't be picked if this was not
272
279
// true. But doesn't hurt to check.
@@ -280,17 +287,17 @@ void ContextVK::Setup(Settings settings) {
280
287
device_info.setPEnabledFeatures (&required_features.value ());
281
288
// Device layers are deprecated and ignored.
282
289
283
- auto device_result = physical_device->createDeviceUnique (device_info);
284
- if (device_result.result != vk::Result::eSuccess) {
285
- VALIDATION_LOG << " Could not create logical device." ;
286
- return ;
290
+ {
291
+ auto device_result =
292
+ device_holder->physical_device .createDeviceUnique (device_info);
293
+ if (device_result.result != vk::Result::eSuccess) {
294
+ VALIDATION_LOG << " Could not create logical device." ;
295
+ return ;
296
+ }
297
+ device_holder->device = std::move (device_result.value );
287
298
}
288
- device_ = std::move (device_result.value );
289
- // This makes sure that the device is deleted at the proper time if there is
290
- // an error.
291
- fml::ScopedCleanupClosure device_resetter ([this ]() { device_.reset (); });
292
299
293
- if (!caps->SetDevice (physical_device. value () )) {
300
+ if (!caps->SetDevice (device_holder-> physical_device )) {
294
301
VALIDATION_LOG << " Capabilities could not be updated." ;
295
302
return ;
296
303
}
@@ -301,9 +308,9 @@ void ContextVK::Setup(Settings settings) {
301
308
auto allocator = std::shared_ptr<AllocatorVK>(new AllocatorVK (
302
309
weak_from_this (), //
303
310
application_info.apiVersion , //
304
- physical_device. value (), //
305
- device_. get () , //
306
- instance.value . get (), //
311
+ device_holder-> physical_device , //
312
+ device_holder , //
313
+ device_holder-> instance .get (), //
307
314
dispatcher.vkGetInstanceProcAddr , //
308
315
dispatcher.vkGetDeviceProcAddr //
309
316
));
@@ -317,7 +324,7 @@ void ContextVK::Setup(Settings settings) {
317
324
// / Setup the pipeline library.
318
325
// /
319
326
auto pipeline_library = std::shared_ptr<PipelineLibraryVK>(
320
- new PipelineLibraryVK (shared_from_this (), //
327
+ new PipelineLibraryVK (device_holder, //
321
328
caps, //
322
329
std::move (settings.cache_directory ), //
323
330
worker_task_runner_ //
@@ -329,10 +336,10 @@ void ContextVK::Setup(Settings settings) {
329
336
}
330
337
331
338
auto sampler_library =
332
- std::shared_ptr<SamplerLibraryVK>(new SamplerLibraryVK (device_. get () ));
339
+ std::shared_ptr<SamplerLibraryVK>(new SamplerLibraryVK (device_holder ));
333
340
334
341
auto shader_library = std::shared_ptr<ShaderLibraryVK>(
335
- new ShaderLibraryVK (weak_from_this (), //
342
+ new ShaderLibraryVK (device_holder, //
336
343
settings.shader_libraries_data ) //
337
344
);
338
345
@@ -345,7 +352,7 @@ void ContextVK::Setup(Settings settings) {
345
352
// / Create the fence waiter.
346
353
// /
347
354
auto fence_waiter =
348
- std::shared_ptr<FenceWaiterVK>(new FenceWaiterVK (device_. get () ));
355
+ std::shared_ptr<FenceWaiterVK>(new FenceWaiterVK (device_holder ));
349
356
if (!fence_waiter->IsValid ()) {
350
357
VALIDATION_LOG << " Could not create fence waiter." ;
351
358
return ;
@@ -354,27 +361,25 @@ void ContextVK::Setup(Settings settings) {
354
361
// ----------------------------------------------------------------------------
355
362
// / Fetch the queues.
356
363
// /
357
- QueuesVK queues (device_ .get (), //
358
- graphics_queue.value (), //
359
- compute_queue.value (), //
360
- transfer_queue.value () //
364
+ QueuesVK queues (device_holder-> device .get (), //
365
+ graphics_queue.value (), //
366
+ compute_queue.value (), //
367
+ transfer_queue.value () //
361
368
);
362
369
if (!queues.IsValid ()) {
363
370
VALIDATION_LOG << " Could not fetch device queues." ;
364
371
return ;
365
372
}
366
373
367
374
VkPhysicalDeviceProperties physical_device_properties;
368
- dispatcher.vkGetPhysicalDeviceProperties (physical_device. value () ,
375
+ dispatcher.vkGetPhysicalDeviceProperties (device_holder-> physical_device ,
369
376
&physical_device_properties);
370
377
371
378
// ----------------------------------------------------------------------------
372
379
// / All done!
373
380
// /
374
- instance_ = std::move (instance. value );
381
+ device_holder_ = std::move (device_holder );
375
382
debug_report_ = std::move (debug_report);
376
- physical_device_ = physical_device.value ();
377
- device_resetter.Release ();
378
383
allocator_ = std::move (allocator);
379
384
shader_library_ = std::move (shader_library);
380
385
sampler_library_ = std::move (sampler_library);
@@ -389,7 +394,7 @@ void ContextVK::Setup(Settings settings) {
389
394
// / Label all the relevant objects. This happens after setup so that the debug
390
395
// / messengers have had a chance to be setup.
391
396
// /
392
- SetDebugName (GetDevice (), device_ .get (), " ImpellerDevice" );
397
+ SetDebugName (GetDevice (), device_holder_-> device .get (), " ImpellerDevice" );
393
398
}
394
399
395
400
// |Context|
@@ -429,11 +434,11 @@ std::shared_ptr<CommandBuffer> ContextVK::CreateCommandBuffer() const {
429
434
}
430
435
431
436
vk::Instance ContextVK::GetInstance () const {
432
- return *instance_ ;
437
+ return *device_holder_-> instance ;
433
438
}
434
439
435
440
const vk::Device& ContextVK::GetDevice () const {
436
- return device_ .get ();
441
+ return device_holder_-> device .get ();
437
442
}
438
443
439
444
const std::shared_ptr<fml::ConcurrentTaskRunner>
@@ -454,12 +459,13 @@ std::unique_ptr<Surface> ContextVK::AcquireNextSurface() {
454
459
455
460
vk::UniqueSurfaceKHR ContextVK::CreateAndroidSurface (
456
461
ANativeWindow* window) const {
457
- if (!instance_ ) {
462
+ if (!device_holder_-> instance ) {
458
463
return vk::UniqueSurfaceKHR{VK_NULL_HANDLE};
459
464
}
460
465
461
466
auto create_info = vk::AndroidSurfaceCreateInfoKHR ().setWindow (window);
462
- auto surface_res = instance_->createAndroidSurfaceKHRUnique (create_info);
467
+ auto surface_res =
468
+ device_holder_->instance ->createAndroidSurfaceKHRUnique (create_info);
463
469
464
470
if (surface_res.result != vk::Result::eSuccess) {
465
471
VALIDATION_LOG << " Could not create Android surface, error: "
@@ -491,7 +497,7 @@ const std::shared_ptr<QueueVK>& ContextVK::GetGraphicsQueue() const {
491
497
}
492
498
493
499
vk::PhysicalDevice ContextVK::GetPhysicalDevice () const {
494
- return physical_device_ ;
500
+ return device_holder_-> physical_device ;
495
501
}
496
502
497
503
std::shared_ptr<FenceWaiterVK> ContextVK::GetFenceWaiter () const {
@@ -505,7 +511,7 @@ std::unique_ptr<CommandEncoderVK> ContextVK::CreateGraphicsCommandEncoder()
505
511
return nullptr ;
506
512
}
507
513
auto encoder = std::unique_ptr<CommandEncoderVK>(new CommandEncoderVK (
508
- weak_from_this (), //
514
+ device_holder_, //
509
515
queues_.graphics_queue , //
510
516
tls_pool, //
511
517
fence_waiter_ //
0 commit comments