@@ -308,7 +308,8 @@ ur_result_t bindlessImagesCreateImpl(ur_context_handle_t hContext,
308
308
ZeImageDesc.pNext = &BindlessDesc;
309
309
310
310
ZeStruct<ze_sampler_desc_t > ZeSamplerDesc;
311
- if (hSampler) {
311
+ const bool WithSampler = hSampler != nullptr ;
312
+ if (WithSampler) {
312
313
ZeSamplerDesc = hSampler->ZeSamplerDesc ;
313
314
BindlessDesc.pNext = &ZeSamplerDesc;
314
315
BindlessDesc.flags |= ZE_IMAGE_BINDLESS_EXP_FLAG_SAMPLED_IMAGE;
@@ -338,7 +339,7 @@ ur_result_t bindlessImagesCreateImpl(ur_context_handle_t hContext,
338
339
MemAllocProperties.type == ZE_MEMORY_TYPE_SHARED) {
339
340
ZeStruct<ze_image_pitched_exp_desc_t > PitchedDesc;
340
341
PitchedDesc.ptr = reinterpret_cast <void *>(hImageMem);
341
- if (hSampler ) {
342
+ if (WithSampler ) {
342
343
ZeSamplerDesc.pNext = &PitchedDesc;
343
344
} else {
344
345
BindlessDesc.pNext = &PitchedDesc;
@@ -372,9 +373,19 @@ ur_result_t bindlessImagesCreateImpl(ur_context_handle_t hContext,
372
373
(ZeImageTranslated, &DeviceOffset));
373
374
*phImage = DeviceOffset;
374
375
375
- std::shared_lock<ur_shared_mutex> Lock (hDevice->Mutex );
376
- hDevice->ZeOffsetToImageHandleMap [*phImage] = ZeImage;
377
- Lock.release ();
376
+ std::shared_lock<ur_shared_mutex> Lock (hDevice->Mutex , std::defer_lock);
377
+ if (WithSampler) {
378
+ // Get a non-exclsuive (shared) read-access to the sampler handle.
379
+ std::shared_lock<ur_shared_mutex> SLock (hSampler->Mutex , std::defer_lock);
380
+ std::scoped_lock LockAll (Lock, SLock);
381
+ // Associate the bindless image with host object handle and sampler handle.
382
+ hDevice->ZeOffsetToImageHandleMap [*phImage] = ZeImage;
383
+ hDevice->ZeImageToSamplerMap [*phImage] = hSampler->ZeSampler ;
384
+ } else {
385
+ Lock.lock ();
386
+ hDevice->ZeOffsetToImageHandleMap [*phImage] = ZeImage;
387
+ Lock.release ();
388
+ }
378
389
return UR_RESULT_SUCCESS;
379
390
}
380
391
@@ -1006,9 +1017,22 @@ ur_result_t urBindlessImagesSampledImageHandleDestroyExp(
1006
1017
ur_context_handle_t hContext, ur_device_handle_t hDevice,
1007
1018
ur_exp_image_native_handle_t hImage) {
1008
1019
// Sampled image is a combination of unsampled image and sampler.
1009
- // Sampler is released in urSamplerRelease.
1010
- return ur::level_zero::urBindlessImagesUnsampledImageHandleDestroyExp (
1011
- hContext, hDevice, hImage);
1020
+ // We destroy the unsampled image image handle first; then the sampler handle.
1021
+ UR_CALL (ur::level_zero::urBindlessImagesUnsampledImageHandleDestroyExp (
1022
+ hContext, hDevice, hImage));
1023
+
1024
+ std::shared_lock<ur_shared_mutex> Lock (hDevice->Mutex );
1025
+ auto Item = hDevice->ZeImageToSamplerMap .find (hImage);
1026
+ if (Item != hDevice->ZeImageToSamplerMap .end ()) {
1027
+ hDevice->ZeImageToSamplerMap .erase (Item);
1028
+ Lock.release ();
1029
+ ZE2UR_CALL (zeSamplerDestroy, (Item->second ));
1030
+ } else {
1031
+ Lock.release ();
1032
+ return UR_RESULT_ERROR_INVALID_NULL_HANDLE;
1033
+ }
1034
+
1035
+ return UR_RESULT_SUCCESS;
1012
1036
}
1013
1037
1014
1038
ur_result_t
0 commit comments