Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Decode] Add ddi implement for vaEndPicture2 #1803

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions media_driver/linux/common/ddi/ddi_media_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ struct DDI_MEDIA_CONTEXT
MEDIA_MUTEX_T ProtMutex = {};
MEDIA_MUTEX_T CmMutex = {};
MEDIA_MUTEX_T MfeMutex = {};
//todo: #if VA_CHECK_VERSION(1, 9, 0)
MEDIA_MUTEX_T SyncFenceMutex = {};
//#endif

// GT system Info
MEDIA_SYSTEM_INFO *pGtSystemInfo = nullptr;
Expand Down
61 changes: 61 additions & 0 deletions media_driver/linux/common/ddi/media_libva.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,9 @@ static VAStatus DdiMedia_HeapInitialize(
DdiMediaUtil_InitMutex(&mediaCtx->ProtMutex);
DdiMediaUtil_InitMutex(&mediaCtx->CmMutex);
DdiMediaUtil_InitMutex(&mediaCtx->MfeMutex);
//todo: #if VA_CHECK_VERSION(1, 9, 0)
DdiMediaUtil_InitMutex(&mediaCtx->SyncFenceMutex);
//#endif

return VA_STATUS_SUCCESS;
}
Expand Down Expand Up @@ -1481,6 +1484,9 @@ static VAStatus DdiMedia_HeapDestroy(
DdiMediaUtil_DestroyMutex(&mediaCtx->ProtMutex);
DdiMediaUtil_DestroyMutex(&mediaCtx->CmMutex);
DdiMediaUtil_DestroyMutex(&mediaCtx->MfeMutex);
//todo: #if VA_CHECK_VERSION(1, 9, 0)
DdiMediaUtil_DestroyMutex(&mediaCtx->SyncFenceMutex);
//#endif

//resource checking
if (mediaCtx->uiNumSurfaces != 0)
Expand Down Expand Up @@ -1558,6 +1564,9 @@ void DestroyMediaContextMutex(PDDI_MEDIA_CONTEXT mediaCtx)
DdiMediaUtil_DestroyMutex(&mediaCtx->VpMutex);
DdiMediaUtil_DestroyMutex(&mediaCtx->CmMutex);
DdiMediaUtil_DestroyMutex(&mediaCtx->MfeMutex);
//todo: #if VA_CHECK_VERSION(1, 9, 0)
DdiMediaUtil_DestroyMutex(&mediaCtx->SyncFenceMutex);
//#endif
#if !defined(ANDROID) && defined(X11_FOUND)
DdiMediaUtil_DestroyMutex(&mediaCtx->PutSurfaceRenderMutex);
DdiMediaUtil_DestroyMutex(&mediaCtx->PutSurfaceSwapBufferMutex);
Expand Down Expand Up @@ -2137,6 +2146,9 @@ VAStatus DdiMedia_LoadFuncion (VADriverContextP ctx)
pVTable->vaBeginPicture = DdiMedia_BeginPicture;
pVTable->vaRenderPicture = DdiMedia_RenderPicture;
pVTable->vaEndPicture = DdiMedia_EndPicture;
//todo: #if VA_CHECK_VERSION(1, 9, 0)
pVTable->vaEndPicture2 = DdiMedia_EndPicture2;
//#endif
pVTable->vaSyncSurface = DdiMedia_SyncSurface;
#if VA_CHECK_VERSION(1, 9, 0)
pVTable->vaSyncSurface2 = DdiMedia_SyncSurface2;
Expand Down Expand Up @@ -4056,6 +4068,55 @@ VAStatus DdiMedia_EndPicture (
return vaStatus;
}

//#if VA_CHECK_VERSION(1, 9, 0) //todo: check correct version
VAStatus DdiMedia_EndPicture2 (
VADriverContextP ctx,
VAContextID context,
int32_t *fences,
int32_t count
)
{
DDI_FUNCTION_ENTER();

DDI_CHK_NULL(ctx, "nullptr ctx", VA_STATUS_ERROR_INVALID_CONTEXT);
DDI_CHK_NULL(fences, "nullptr fences", VA_STATUS_ERROR_INVALID_PARAMETER);

uint32_t ctxType = DDI_MEDIA_CONTEXT_TYPE_NONE;
void *ctxPtr = DdiMedia_GetContextFromContextID(ctx, context, &ctxType);
PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
VAStatus vaStatus = VA_STATUS_SUCCESS;

DdiMediaUtil_LockMutex(&mediaCtx->SyncFenceMutex);
vaStatus = DdiMedia_SetSyncFences(ctx, context, fences, count);
//todo: add fences[1...count] into bufmgr->fences[...]

switch (ctxType)
{
case DDI_MEDIA_CONTEXT_TYPE_DECODER:
vaStatus = DdiDecode_EndPicture(ctx, context);
break;
case DDI_MEDIA_CONTEXT_TYPE_ENCODER:
vaStatus = DdiEncode_EndPicture(ctx, context);
break;
case DDI_MEDIA_CONTEXT_TYPE_VP:
vaStatus = DdiVp_EndPicture(ctx, context);
break;
default:
DDI_ASSERTMESSAGE("DDI: unsupported context in DdiCodec_EndPicture.");
vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
}

vaStatus = DdiMedia_GetSyncFenceOut(ctx, context, &fences[0]);
//todo: get fence out from bufmgr->fence[0]
DdiMediaUtil_UnLockMutex(&mediaCtx->SyncFenceMutex);

MOS_TraceEventExt(EVENT_VA_PICTURE, EVENT_TYPE_END, &context, sizeof(context), &vaStatus, sizeof(vaStatus));
PERF_UTILITY_STOP_ONCE("First Frame Time", PERF_MOS, PERF_LEVEL_DDI);

return vaStatus;
}
//#endif

static VAStatus DdiMedia_StatusCheck (
PDDI_MEDIA_CONTEXT mediaCtx,
DDI_MEDIA_SURFACE *surface,
Expand Down
9 changes: 9 additions & 0 deletions media_driver/linux/common/ddi/media_libva.h
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,15 @@ VAStatus DdiMedia_EndPicture (
VAContextID context
);

//#if VA_CHECK_VERSION(1, 9, 0) //todo: check correct version
VAStatus DdiMedia_EndPicture2 (
VADriverContextP ctx,
VAContextID context,
int32_t *fences,
int32_t count
);
//#endif

//!
//! \brief Sync surface
//! \details This function blocks until all pending operations on the render target
Expand Down
31 changes: 31 additions & 0 deletions media_driver/linux/common/ddi/media_libva_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -475,3 +475,34 @@ void MovePriorityBufferIdToEnd (VABufferID *buffers, int32_t priorityIndexInBuf,
}
}

VAStatus DdiMedia_SetSyncFences(VADriverContextP ctx, VAContextID context, int32_t *fences, int32_t count)
{
VAStatus vaStatus = VA_STATUS_SUCCESS;
PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
struct mos_exec_fences exec_fences;
exec_fences.fences = fences;
exec_fences.count = count;
int ret = mos_set_fences(mediaCtx->pDrmBufMgr, &exec_fences);

if (ret)
{
vaStatus = VA_STATUS_ERROR_OPERATION_FAILED;
}

return vaStatus;
}

VAStatus DdiMedia_GetSyncFenceOut(VADriverContextP ctx, VAContextID context, int32_t *fence_out)
{
VAStatus vaStatus = VA_STATUS_SUCCESS;
PDDI_MEDIA_CONTEXT mediaCtx = DdiMedia_GetMediaContext(ctx);
int ret = mos_get_fence(mediaCtx->pDrmBufMgr, fence_out);

if (ret)
{
vaStatus = VA_STATUS_ERROR_OPERATION_FAILED;
*fence_out = 0;
}

return vaStatus;
}
10 changes: 10 additions & 0 deletions media_driver/linux/common/ddi/media_libva_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,4 +273,14 @@ int32_t DdiMedia_GetGpuPriority (VADriverContextP ctx, VABufferID *buffers, int3
//!
void MovePriorityBufferIdToEnd (VABufferID *buffers, int32_t priorityIndexInBuf, int32_t numBuffers);

//!
//! \brief Add fence fds into bufmgr for execution sync
//!
VAStatus DdiMedia_SetSyncFences(VADriverContextP ctx, VAContextID context, int32_t *fences, int32_t count);

//!
//! \brief Get fence out from current execution submission
//!
VAStatus DdiMedia_GetSyncFenceOut(VADriverContextP ctx, VAContextID context, int32_t *fence_out);

#endif
10 changes: 10 additions & 0 deletions media_softlet/linux/common/os/i915/include/mos_bufmgr_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,13 @@ struct mos_drm_uc_version {
uint32_t minor_version;
};

struct mos_exec_fences
{
#define FENCES_MAX 10
int32_t *fences;
int32_t count;
};

struct mos_linux_bo *mos_bo_alloc(struct mos_bufmgr *bufmgr,
struct mos_drm_bo_alloc *alloc);
struct mos_linux_bo *mos_bo_alloc_userptr(struct mos_bufmgr *bufmgr,
Expand Down Expand Up @@ -312,6 +319,9 @@ int mos_bufmgr_get_memory_info(struct mos_bufmgr *bufmgr, char *info, uint32_t l
int mos_bufmgr_get_devid(struct mos_bufmgr *bufmgr);
void mos_bufmgr_realloc_cache(struct mos_bufmgr *bufmgr, uint8_t alloc_mode);

int mos_set_fences(struct mos_bufmgr *bufmgr, struct mos_exec_fences *exec_fences);
int mos_get_fence(struct mos_bufmgr *bufmgr, int32_t *fence_out);

int mos_bo_map_unsynchronized(struct mos_linux_bo *bo);
int mos_bo_map_gtt(struct mos_linux_bo *bo);
int mos_bo_unmap_gtt(struct mos_linux_bo *bo);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,9 @@ struct mos_bufmgr {
uint8_t (*switch_off_n_bits)(struct mos_linux_context *ctx, uint8_t in_mask, int n) = nullptr;
unsigned int (*hweight8)(struct mos_linux_context *ctx, uint8_t w) = nullptr;

int (*set_fences)(struct mos_bufmgr *bufmgr, struct mos_exec_fences *exec_fences) = nullptr;
int (*get_fence)(struct mos_bufmgr *bufmgr, int32_t *fence_out) = nullptr;

/**< Enables verbose debugging printouts */
int debug = 0;
uint32_t *get_reserved = nullptr;
Expand Down
143 changes: 140 additions & 3 deletions media_softlet/linux/common/os/i915/mos_bufmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ struct mos_bufmgr_gem {
int exec_size;
int exec_count;

struct mos_exec_fences exec_fences;

/** Array of lists of cached gem objects of power-of-two sizes */
struct mos_gem_bo_bucket cache_bucket[64];
int num_buckets;
Expand Down Expand Up @@ -2459,9 +2461,10 @@ mos_bufmgr_gem_destroy(struct mos_bufmgr *bufmgr)
struct drm_gem_close close_bo;
int ret;

free(bufmgr_gem->exec2_objects);
free(bufmgr_gem->exec_objects);
free(bufmgr_gem->exec_bos);
mos_safe_free(bufmgr_gem->exec2_objects);
mos_safe_free(bufmgr_gem->exec_objects);
mos_safe_free(bufmgr_gem->exec_bos);
mos_safe_free(bufmgr_gem->exec_fences.fences);
pthread_mutex_destroy(&bufmgr_gem->lock);

/* Free any cached buffer objects we were going to reuse */
Expand Down Expand Up @@ -2962,6 +2965,79 @@ mos_update_buffer_offsets2 (struct mos_bufmgr_gem *bufmgr_gem, mos_linux_context
}
}

//todo: to move synchronization_xe.h to os common instead of xe specific
#include "mos_synchronization_xe.h"

int
__add_eb_fence_array(struct mos_bufmgr_gem *bufmgr_gem,
struct drm_i915_gem_execbuffer2 *eb,
unsigned int flags)
{
#define SCALABILITY_ON (I915_EXEC_FENCE_OUT | I915_EXEC_FENCE_IN | I915_EXEC_FENCE_SUBMIT)

//Ignore multi batch submission for scalability to simplify logic
//todo: check has_fence_array from params
if (!(flags & SCALABILITY_ON)
&& bufmgr_gem->exec_fences.fences)
{
int32_t fence_count = bufmgr_gem->exec_fences.count;
int32_t *exec_fences = bufmgr_gem->exec_fences.fences;

if (fence_count > 0)
{
struct drm_i915_gem_exec_fence *fences
= (struct drm_i915_gem_exec_fence *)malloc(fence_count * sizeof(struct drm_i915_gem_exec_fence));
if (fences == nullptr)
{
return -ENOMEM;
}
for (int32_t i = 0; i < fence_count; i++)
{
fences[i].handle = mos_sync_syncfile_fd_to_syncobj_handle(bufmgr_gem->fd, exec_fences[i + 1]);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to check if exec_fences[i + 1] is valid and imported status; Ignore invalid one.

fences[i].flags = I915_EXEC_FENCE_WAIT;
}

eb->num_cliprects = fence_count;
eb->cliprects_ptr = (uintptr_t)fences;
eb->flags |= I915_EXEC_FENCE_ARRAY;
}

eb->rsvd2 = -1;
eb->flags |= I915_EXEC_FENCE_OUT; //todo: to verify rsvd2 >> 32 still has fence out
return 0;
}
else
{
return 0;
}
}

void
__clear_eb_fence_array(struct mos_bufmgr_gem *bufmgr_gem,
struct drm_i915_gem_execbuffer2 *eb)
{
if (eb->cliprects_ptr
&& eb->flags & I915_EXEC_FENCE_ARRAY)
{
struct drm_i915_gem_exec_fence *fences = (drm_i915_gem_exec_fence *)eb->cliprects_ptr;

for (int32_t i = 0; i < eb->num_cliprects; i++)
{
mos_sync_syncobj_destroy(bufmgr_gem->fd, fences[i].handle);
}

mos_safe_free(fences);
eb->cliprects_ptr = (uintptr_t)nullptr;
}

if (bufmgr_gem->exec_fences.fences
&& eb->flags & I915_EXEC_FENCE_OUT)
{
bufmgr_gem->exec_fences.fences[0] = eb->rsvd2 >> 32;
}

}

drm_export int
do_exec2(struct mos_linux_bo *bo, int used, struct mos_linux_context *ctx,
drm_clip_rect_t *cliprects, int num_cliprects, int DR4,
Expand Down Expand Up @@ -3033,6 +3109,8 @@ do_exec2(struct mos_linux_bo *bo, int used, struct mos_linux_context *ctx,
if (bufmgr_gem->no_exec)
goto skip_execution;

__add_eb_fence_array(bufmgr_gem, &execbuf, flags);

ret = drmIoctl(bufmgr_gem->fd,
DRM_IOCTL_I915_GEM_EXECBUFFER2_WR,
&execbuf);
Expand All @@ -3059,6 +3137,8 @@ do_exec2(struct mos_linux_bo *bo, int used, struct mos_linux_context *ctx,
*fence = execbuf.rsvd2 >> 32;
}

__clear_eb_fence_array(bufmgr_gem, &execbuf);

skip_execution:
if (bufmgr_gem->bufmgr.debug)
mos_gem_dump_validation_list(bufmgr_gem);
Expand Down Expand Up @@ -5221,6 +5301,61 @@ mos_bufmgr_enable_turbo_boost(struct mos_bufmgr *bufmgr)
DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &ctxParam );
}

int
mos_bufmgr_set_fences(struct mos_bufmgr *bufmgr, struct mos_exec_fences *exec_fences)
{
if (!bufmgr || !exec_fences || exec_fences->count > FENCES_MAX)
{
return -EINVAL;
}

struct mos_bufmgr_gem *bufmgr_gem = (struct mos_bufmgr_gem *)bufmgr;

if (bufmgr_gem->exec_fences.fences == nullptr)
{
//fences[0] reserved for fence out
bufmgr_gem->exec_fences.fences = (int32_t *)malloc((FENCES_MAX + 1) * sizeof(int32_t));

if (bufmgr_gem->exec_fences.fences == nullptr)
{
return -ENOMEM;
}

bufmgr_gem->exec_fences.count = 0;
}

if (exec_fences->count > 0)
{
memcpy(bufmgr_gem->exec_fences.fences, exec_fences->fences, (exec_fences->count + 1) * sizeof(int32_t));
bufmgr_gem->exec_fences.fences[0] = 0;
bufmgr_gem->exec_fences.count = exec_fences->count;
}

return 0;
}

int
mos_bufmgr_get_fence(struct mos_bufmgr *bufmgr, int32_t *fence_out)
{
if (!bufmgr || !fence_out)
{
return -EINVAL;
}

struct mos_bufmgr_gem *bufmgr_gem = (struct mos_bufmgr_gem *)bufmgr;

if (bufmgr_gem->exec_fences.fences)
{
*fence_out = bufmgr_gem->exec_fences.fences[0];
}
else
{
*fence_out = 0;
}

return 0;
}

/**
* Initializes the GEM buffer manager, which uses the kernel to allocate, map,
* and manage map buffer objections.
Expand Down Expand Up @@ -5333,6 +5468,8 @@ mos_bufmgr_gem_init_i915(int fd, int batch_size)
bufmgr_gem->bufmgr.get_ts_frequency = mos_bufmgr_get_ts_frequency;
bufmgr_gem->bufmgr.has_bsd2 = mos_bufmgr_has_bsd2;
bufmgr_gem->bufmgr.enable_turbo_boost = mos_bufmgr_enable_turbo_boost;
bufmgr_gem->bufmgr.set_fences = mos_bufmgr_set_fences;
bufmgr_gem->bufmgr.get_fence = mos_bufmgr_get_fence;

bufmgr_gem->mem_profiler_path = getenv("MEDIA_MEMORY_PROFILER_LOG");
if (bufmgr_gem->mem_profiler_path != nullptr)
Expand Down
Loading
Loading