@@ -107,8 +107,8 @@ uint64_t CalculateHash(void* ptr) {
107107ContextVK::ContextVK () : hash_(CalculateHash(this )) {}
108108
109109ContextVK::~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 ();
112112 }
113113 CommandPoolVK::ClearAllPools (this );
114114}
@@ -191,14 +191,17 @@ void ContextVK::Setup(Settings settings) {
191191 instance_info.setPApplicationInfo (&application_info);
192192 instance_info.setFlags (instance_flags);
193193
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 );
199203 }
200-
201- dispatcher.init (instance.value .get ());
204+ dispatcher.init (device_holder->instance .get ());
202205
203206 // ----------------------------------------------------------------------------
204207 // / Setup the debug report.
@@ -207,7 +210,7 @@ void ContextVK::Setup(Settings settings) {
207210 // / initialization issues.
208211 // /
209212 auto debug_report =
210- std::make_unique<DebugReportVK>(*caps, instance. value .get ());
213+ std::make_unique<DebugReportVK>(*caps, device_holder-> instance .get ());
211214
212215 if (!debug_report->IsValid ()) {
213216 VALIDATION_LOG << " Could not setup debug report." ;
@@ -217,21 +220,25 @@ void ContextVK::Setup(Settings settings) {
217220 // ----------------------------------------------------------------------------
218221 // / Pick the physical device.
219222 // /
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 ());
224231 }
225232
226233 // ----------------------------------------------------------------------------
227234 // / Pick device queues.
228235 // /
229236 auto graphics_queue =
230- PickQueue (physical_device. value () , vk::QueueFlagBits::eGraphics);
237+ PickQueue (device_holder-> physical_device , vk::QueueFlagBits::eGraphics);
231238 auto transfer_queue =
232- PickQueue (physical_device. value () , vk::QueueFlagBits::eTransfer);
239+ PickQueue (device_holder-> physical_device , vk::QueueFlagBits::eTransfer);
233240 auto compute_queue =
234- PickQueue (physical_device. value () , vk::QueueFlagBits::eCompute);
241+ PickQueue (device_holder-> physical_device , vk::QueueFlagBits::eCompute);
235242
236243 if (!graphics_queue.has_value ()) {
237244 VALIDATION_LOG << " Could not pick graphics queue." ;
@@ -250,7 +257,7 @@ void ContextVK::Setup(Settings settings) {
250257 // / Create the logical device.
251258 // /
252259 auto enabled_device_extensions =
253- caps->GetRequiredDeviceExtensions (physical_device. value () );
260+ caps->GetRequiredDeviceExtensions (device_holder-> physical_device );
254261 if (!enabled_device_extensions.has_value ()) {
255262 // This shouldn't happen since we already did device selection. But doesn't
256263 // hurt to check again.
@@ -266,7 +273,7 @@ void ContextVK::Setup(Settings settings) {
266273 {graphics_queue.value (), compute_queue.value (), transfer_queue.value ()});
267274
268275 const auto required_features =
269- caps->GetRequiredDeviceFeatures (physical_device. value () );
276+ caps->GetRequiredDeviceFeatures (device_holder-> physical_device );
270277 if (!required_features.has_value ()) {
271278 // This shouldn't happen since the device can't be picked if this was not
272279 // true. But doesn't hurt to check.
@@ -280,17 +287,17 @@ void ContextVK::Setup(Settings settings) {
280287 device_info.setPEnabledFeatures (&required_features.value ());
281288 // Device layers are deprecated and ignored.
282289
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 );
287298 }
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 (); });
292299
293- if (!caps->SetDevice (physical_device. value () )) {
300+ if (!caps->SetDevice (device_holder-> physical_device )) {
294301 VALIDATION_LOG << " Capabilities could not be updated." ;
295302 return ;
296303 }
@@ -301,9 +308,9 @@ void ContextVK::Setup(Settings settings) {
301308 auto allocator = std::shared_ptr<AllocatorVK>(new AllocatorVK (
302309 weak_from_this (), //
303310 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 (), //
307314 dispatcher.vkGetInstanceProcAddr , //
308315 dispatcher.vkGetDeviceProcAddr //
309316 ));
@@ -317,7 +324,7 @@ void ContextVK::Setup(Settings settings) {
317324 // / Setup the pipeline library.
318325 // /
319326 auto pipeline_library = std::shared_ptr<PipelineLibraryVK>(
320- new PipelineLibraryVK (shared_from_this (), //
327+ new PipelineLibraryVK (device_holder, //
321328 caps, //
322329 std::move (settings.cache_directory ), //
323330 worker_task_runner_ //
@@ -329,10 +336,10 @@ void ContextVK::Setup(Settings settings) {
329336 }
330337
331338 auto sampler_library =
332- std::shared_ptr<SamplerLibraryVK>(new SamplerLibraryVK (device_. get () ));
339+ std::shared_ptr<SamplerLibraryVK>(new SamplerLibraryVK (device_holder ));
333340
334341 auto shader_library = std::shared_ptr<ShaderLibraryVK>(
335- new ShaderLibraryVK (weak_from_this (), //
342+ new ShaderLibraryVK (device_holder, //
336343 settings.shader_libraries_data ) //
337344 );
338345
@@ -345,7 +352,7 @@ void ContextVK::Setup(Settings settings) {
345352 // / Create the fence waiter.
346353 // /
347354 auto fence_waiter =
348- std::shared_ptr<FenceWaiterVK>(new FenceWaiterVK (device_. get () ));
355+ std::shared_ptr<FenceWaiterVK>(new FenceWaiterVK (device_holder ));
349356 if (!fence_waiter->IsValid ()) {
350357 VALIDATION_LOG << " Could not create fence waiter." ;
351358 return ;
@@ -354,27 +361,25 @@ void ContextVK::Setup(Settings settings) {
354361 // ----------------------------------------------------------------------------
355362 // / Fetch the queues.
356363 // /
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 () //
361368 );
362369 if (!queues.IsValid ()) {
363370 VALIDATION_LOG << " Could not fetch device queues." ;
364371 return ;
365372 }
366373
367374 VkPhysicalDeviceProperties physical_device_properties;
368- dispatcher.vkGetPhysicalDeviceProperties (physical_device. value () ,
375+ dispatcher.vkGetPhysicalDeviceProperties (device_holder-> physical_device ,
369376 &physical_device_properties);
370377
371378 // ----------------------------------------------------------------------------
372379 // / All done!
373380 // /
374- instance_ = std::move (instance. value );
381+ device_holder_ = std::move (device_holder );
375382 debug_report_ = std::move (debug_report);
376- physical_device_ = physical_device.value ();
377- device_resetter.Release ();
378383 allocator_ = std::move (allocator);
379384 shader_library_ = std::move (shader_library);
380385 sampler_library_ = std::move (sampler_library);
@@ -389,7 +394,7 @@ void ContextVK::Setup(Settings settings) {
389394 // / Label all the relevant objects. This happens after setup so that the debug
390395 // / messengers have had a chance to be setup.
391396 // /
392- SetDebugName (GetDevice (), device_ .get (), " ImpellerDevice" );
397+ SetDebugName (GetDevice (), device_holder_-> device .get (), " ImpellerDevice" );
393398}
394399
395400// |Context|
@@ -429,11 +434,11 @@ std::shared_ptr<CommandBuffer> ContextVK::CreateCommandBuffer() const {
429434}
430435
431436vk::Instance ContextVK::GetInstance () const {
432- return *instance_ ;
437+ return *device_holder_-> instance ;
433438}
434439
435440const vk::Device& ContextVK::GetDevice () const {
436- return device_ .get ();
441+ return device_holder_-> device .get ();
437442}
438443
439444const std::shared_ptr<fml::ConcurrentTaskRunner>
@@ -454,12 +459,13 @@ std::unique_ptr<Surface> ContextVK::AcquireNextSurface() {
454459
455460vk::UniqueSurfaceKHR ContextVK::CreateAndroidSurface (
456461 ANativeWindow* window) const {
457- if (!instance_ ) {
462+ if (!device_holder-> instance ) {
458463 return vk::UniqueSurfaceKHR{VK_NULL_HANDLE};
459464 }
460465
461466 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);
463469
464470 if (surface_res.result != vk::Result::eSuccess) {
465471 VALIDATION_LOG << " Could not create Android surface, error: "
@@ -491,7 +497,7 @@ const std::shared_ptr<QueueVK>& ContextVK::GetGraphicsQueue() const {
491497}
492498
493499vk::PhysicalDevice ContextVK::GetPhysicalDevice () const {
494- return physical_device_ ;
500+ return device_holder_-> physical_device ;
495501}
496502
497503std::shared_ptr<FenceWaiterVK> ContextVK::GetFenceWaiter () const {
@@ -505,7 +511,7 @@ std::unique_ptr<CommandEncoderVK> ContextVK::CreateGraphicsCommandEncoder()
505511 return nullptr ;
506512 }
507513 auto encoder = std::unique_ptr<CommandEncoderVK>(new CommandEncoderVK (
508- weak_from_this (), //
514+ device_holder_, //
509515 queues_.graphics_queue , //
510516 tls_pool, //
511517 fence_waiter_ //
0 commit comments