@@ -2461,9 +2461,10 @@ mos_bufmgr_gem_destroy(struct mos_bufmgr *bufmgr)
24612461 struct drm_gem_close close_bo ;
24622462 int ret ;
24632463
2464- free (bufmgr_gem -> exec2_objects );
2465- free (bufmgr_gem -> exec_objects );
2466- free (bufmgr_gem -> exec_bos );
2464+ mos_safe_free (bufmgr_gem -> exec2_objects );
2465+ mos_safe_free (bufmgr_gem -> exec_objects );
2466+ mos_safe_free (bufmgr_gem -> exec_bos );
2467+ mos_safe_free (bufmgr_gem -> exec_fences .fences );
24672468 pthread_mutex_destroy (& bufmgr_gem -> lock );
24682469
24692470 /* Free any cached buffer objects we were going to reuse */
@@ -2964,6 +2965,71 @@ mos_update_buffer_offsets2 (struct mos_bufmgr_gem *bufmgr_gem, mos_linux_context
29642965 }
29652966}
29662967
2968+ //todo: to move synchronization_xe.h to os common instead of xe specific
2969+ #include "mos_synchronization_xe.h"
2970+
2971+ int
2972+ __add_eb_fence_array (struct mos_bufmgr_gem * bufmgr_gem ,
2973+ struct drm_i915_gem_execbuffer2 * eb ,
2974+ unsigned int flags )
2975+ {
2976+ #define SCALABILITY_ON (I915_EXEC_FENCE_OUT | I915_EXEC_FENCE_IN | I915_EXEC_FENCE_SUBMIT)
2977+
2978+ //Ignore multi batch submission for scalability to simplify logic
2979+ //todo: check has_fence_array from params
2980+ if (!(flags & SCALABILITY_ON )
2981+ && bufmgr_gem -> exec_fences .fences
2982+ && bufmgr_gem -> exec_fences .count > 0 )
2983+ {
2984+ int32_t fence_count = bufmgr_gem -> exec_fences .count ;
2985+ int32_t * exec_fences = bufmgr_gem -> exec_fences .fences ;
2986+ struct drm_i915_gem_exec_fence * fences
2987+ = (struct drm_i915_gem_exec_fence * )malloc (fence_count * sizeof (struct drm_i915_gem_exec_fence ));
2988+ if (fences == nullptr )
2989+ {
2990+ return - ENOMEM ;
2991+ }
2992+ for (int32_t i = 0 ; i < fence_count ; i ++ )
2993+ {
2994+ fences [i ].handle = mos_sync_syncfile_fd_to_syncobj_handle (bufmgr_gem -> fd , exec_fences [i + 1 ]);
2995+ fences [i ].flags = I915_EXEC_FENCE_WAIT ;
2996+ }
2997+
2998+ eb -> num_cliprects = fence_count ;
2999+ eb -> cliprects_ptr = (uintptr_t )fences ;
3000+ eb -> rsvd2 = -1 ;
3001+ eb -> flags |= (I915_EXEC_FENCE_ARRAY | I915_EXEC_FENCE_OUT ); //todo: to verify rsvd2 >> 32 still has fence out
3002+ return 0 ;
3003+ }
3004+ else
3005+ {
3006+ return 0 ;
3007+ }
3008+ }
3009+
3010+ void
3011+ __clear_eb_fence_array (struct mos_bufmgr_gem * bufmgr_gem ,
3012+ struct drm_i915_gem_execbuffer2 * eb )
3013+ {
3014+ if (eb -> cliprects_ptr
3015+ && eb -> flags & I915_EXEC_FENCE_ARRAY )
3016+ {
3017+ struct drm_i915_gem_exec_fence * fences = (drm_i915_gem_exec_fence * )eb -> cliprects_ptr ;
3018+
3019+ for (int32_t i = 0 ; i < eb -> num_cliprects ; i ++ )
3020+ {
3021+ mos_sync_syncobj_destroy (bufmgr_gem -> fd , fences [i ].handle );
3022+ }
3023+
3024+ if (bufmgr_gem -> exec_fences .fences )
3025+ {
3026+ bufmgr_gem -> exec_fences .fences [0 ] = eb -> rsvd2 >> 32 ;
3027+ }
3028+ mos_safe_free (fences );
3029+ eb -> cliprects_ptr = (uintptr_t )nullptr ;
3030+ }
3031+ }
3032+
29673033drm_export int
29683034do_exec2 (struct mos_linux_bo * bo , int used , struct mos_linux_context * ctx ,
29693035 drm_clip_rect_t * cliprects , int num_cliprects , int DR4 ,
@@ -3035,6 +3101,8 @@ do_exec2(struct mos_linux_bo *bo, int used, struct mos_linux_context *ctx,
30353101 if (bufmgr_gem -> no_exec )
30363102 goto skip_execution ;
30373103
3104+ __add_eb_fence_array (bufmgr_gem , & execbuf , flags );
3105+
30383106 ret = drmIoctl (bufmgr_gem -> fd ,
30393107 DRM_IOCTL_I915_GEM_EXECBUFFER2_WR ,
30403108 & execbuf );
@@ -3061,6 +3129,8 @@ do_exec2(struct mos_linux_bo *bo, int used, struct mos_linux_context *ctx,
30613129 * fence = execbuf .rsvd2 >> 32 ;
30623130 }
30633131
3132+ __clear_eb_fence_array (bufmgr_gem , & execbuf );
3133+
30643134skip_execution :
30653135 if (bufmgr_gem -> bufmgr .debug )
30663136 mos_gem_dump_validation_list (bufmgr_gem );
0 commit comments