@@ -2461,9 +2461,10 @@ mos_bufmgr_gem_destroy(struct mos_bufmgr *bufmgr)
2461
2461
struct drm_gem_close close_bo ;
2462
2462
int ret ;
2463
2463
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 );
2467
2468
pthread_mutex_destroy (& bufmgr_gem -> lock );
2468
2469
2469
2470
/* Free any cached buffer objects we were going to reuse */
@@ -2964,6 +2965,79 @@ mos_update_buffer_offsets2 (struct mos_bufmgr_gem *bufmgr_gem, mos_linux_context
2964
2965
}
2965
2966
}
2966
2967
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
+ {
2983
+ int32_t fence_count = bufmgr_gem -> exec_fences .count ;
2984
+ int32_t * exec_fences = bufmgr_gem -> exec_fences .fences ;
2985
+
2986
+ if (fence_count > 0 )
2987
+ {
2988
+ struct drm_i915_gem_exec_fence * fences
2989
+ = (struct drm_i915_gem_exec_fence * )malloc (fence_count * sizeof (struct drm_i915_gem_exec_fence ));
2990
+ if (fences == nullptr )
2991
+ {
2992
+ return - ENOMEM ;
2993
+ }
2994
+ for (int32_t i = 0 ; i < fence_count ; i ++ )
2995
+ {
2996
+ fences [i ].handle = mos_sync_syncfile_fd_to_syncobj_handle (bufmgr_gem -> fd , exec_fences [i + 1 ]);
2997
+ fences [i ].flags = I915_EXEC_FENCE_WAIT ;
2998
+ }
2999
+
3000
+ eb -> num_cliprects = fence_count ;
3001
+ eb -> cliprects_ptr = (uintptr_t )fences ;
3002
+ eb -> flags |= I915_EXEC_FENCE_ARRAY ;
3003
+ }
3004
+
3005
+ eb -> rsvd2 = -1 ;
3006
+ eb -> flags |= I915_EXEC_FENCE_OUT ; //todo: to verify rsvd2 >> 32 still has fence out
3007
+ return 0 ;
3008
+ }
3009
+ else
3010
+ {
3011
+ return 0 ;
3012
+ }
3013
+ }
3014
+
3015
+ void
3016
+ __clear_eb_fence_array (struct mos_bufmgr_gem * bufmgr_gem ,
3017
+ struct drm_i915_gem_execbuffer2 * eb )
3018
+ {
3019
+ if (eb -> cliprects_ptr
3020
+ && eb -> flags & I915_EXEC_FENCE_ARRAY )
3021
+ {
3022
+ struct drm_i915_gem_exec_fence * fences = (drm_i915_gem_exec_fence * )eb -> cliprects_ptr ;
3023
+
3024
+ for (int32_t i = 0 ; i < eb -> num_cliprects ; i ++ )
3025
+ {
3026
+ mos_sync_syncobj_destroy (bufmgr_gem -> fd , fences [i ].handle );
3027
+ }
3028
+
3029
+ mos_safe_free (fences );
3030
+ eb -> cliprects_ptr = (uintptr_t )nullptr ;
3031
+ }
3032
+
3033
+ if (bufmgr_gem -> exec_fences .fences
3034
+ && eb -> flags & I915_EXEC_FENCE_OUT )
3035
+ {
3036
+ bufmgr_gem -> exec_fences .fences [0 ] = eb -> rsvd2 >> 32 ;
3037
+ }
3038
+
3039
+ }
3040
+
2967
3041
drm_export int
2968
3042
do_exec2 (struct mos_linux_bo * bo , int used , struct mos_linux_context * ctx ,
2969
3043
drm_clip_rect_t * cliprects , int num_cliprects , int DR4 ,
@@ -3035,6 +3109,8 @@ do_exec2(struct mos_linux_bo *bo, int used, struct mos_linux_context *ctx,
3035
3109
if (bufmgr_gem -> no_exec )
3036
3110
goto skip_execution ;
3037
3111
3112
+ __add_eb_fence_array (bufmgr_gem , & execbuf , flags );
3113
+
3038
3114
ret = drmIoctl (bufmgr_gem -> fd ,
3039
3115
DRM_IOCTL_I915_GEM_EXECBUFFER2_WR ,
3040
3116
& execbuf );
@@ -3061,6 +3137,8 @@ do_exec2(struct mos_linux_bo *bo, int used, struct mos_linux_context *ctx,
3061
3137
* fence = execbuf .rsvd2 >> 32 ;
3062
3138
}
3063
3139
3140
+ __clear_eb_fence_array (bufmgr_gem , & execbuf );
3141
+
3064
3142
skip_execution :
3065
3143
if (bufmgr_gem -> bufmgr .debug )
3066
3144
mos_gem_dump_validation_list (bufmgr_gem );
0 commit comments