@@ -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,71 @@ 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
+ && 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
+ fences [i ].handle = 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
+
2967
3033
drm_export int
2968
3034
do_exec2 (struct mos_linux_bo * bo , int used , struct mos_linux_context * ctx ,
2969
3035
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,
3035
3101
if (bufmgr_gem -> no_exec )
3036
3102
goto skip_execution ;
3037
3103
3104
+ __add_eb_fence_array (bufmgr_gem , & execbuf , flags );
3105
+
3038
3106
ret = drmIoctl (bufmgr_gem -> fd ,
3039
3107
DRM_IOCTL_I915_GEM_EXECBUFFER2_WR ,
3040
3108
& execbuf );
@@ -3061,6 +3129,8 @@ do_exec2(struct mos_linux_bo *bo, int used, struct mos_linux_context *ctx,
3061
3129
* fence = execbuf .rsvd2 >> 32 ;
3062
3130
}
3063
3131
3132
+ __clear_eb_fence_array (bufmgr_gem , & execbuf );
3133
+
3064
3134
skip_execution :
3065
3135
if (bufmgr_gem -> bufmgr .debug )
3066
3136
mos_gem_dump_validation_list (bufmgr_gem );
0 commit comments