Software Version
DRIVE OS Linux 6.0.8.1 and DriveWorks 5.10
Hardware Platform
DRIVE AGX Orin
Hi,
According to the documentation of NvMedia2DFillNvSciSyncAttrList, it sets NvSciSyncAttrKey_RequiredPerm and NvSciSyncAttrKey_PrimitiveInfo.
I try to manually fill a NvSciSyncAttrList with all the attributes that would be filled by NvMedia2DFillNvSciSyncAttrList:
// fill hwSignalerSyncAttrs
{
/* If I uncomment, it works
if(auto const error{NvMedia2DFillNvSciSyncAttrList(nvMedia2D, hwSignalerSyncAttrs.get(), NVMEDIA_SIGNALER)}; error != NVMEDIA_STATUS_OK)
{
LOG_ERR("Couldn't set NvSciSyncAttrList: %d", error);
return {};
}*/
static constexpr bool cpuSignaler{false};
static constexpr NvSciSyncAccessPerm hwPerm{NvSciSyncAccessPerm_SignalOnly};
static constexpr NvSciSyncAttrValPrimitiveType hwPrimType[]{
NvSciSyncAttrValPrimitiveType_Syncpoint,
NvSciSyncAttrValPrimitiveType_SysmemSemaphore,
NvSciSyncAttrValPrimitiveType_SysmemSemaphorePayload64b,
};
static constexpr NvSciBufPeerHwEngine hwEngines[]{
NvSciBufPeerHwEngine{ NvSciBufHwEngName_Vic, NvSciBufPlatformName_Orin },
NvSciBufPeerHwEngine{ NvSciBufHwEngName_MSENC, NvSciBufPlatformName_Orin },
NvSciBufPeerHwEngine{ NvSciBufHwEngName_Gpu, NvSciBufPlatformName_Orin },
};
static std::vector<NvSciRmGpuId> const& gpuIds{getGpuIds()};
if(gpuIds.empty())
{
LOG_ERR("Couldn't get GPU vector.");
return {};
}
NvSciSyncAttrKeyValuePair hwKeyValuePairs[] = {
{ NvSciSyncAttrKey_NeedCpuAccess, &cpuSignaler, sizeof(cpuSignaler) },
{ NvSciSyncAttrKey_RequiredPerm, &hwPerm, sizeof(hwPerm) },
{ NvSciSyncAttrKey_PrimitiveInfo, &hwPrimType, sizeof(hwPrimType) },
{ NvSciSyncAttrKey_GpuId, gpuIds.data(), sizeof(NvSciRmGpuId) * gpuIds.size() },
{ NvSciSyncAttrKey_PeerHwEngineArray, &hwEngines, sizeof(hwEngines) },
};
if(auto const error{NvSciSyncAttrListSetAttrs(hwSignalerSyncAttrs.get(), hwKeyValuePairs, sizeof(hwKeyValuePairs) / sizeof(hwKeyValuePairs))}; error != NvSciError_Success)
{
LOG_ERR("Couldn't set NvSciSyncAttrList: %d", error);
return {};
}
}
// fill waiterSyncAttrs
{
/* If I uncomment, it works
if(auto const error{NvMedia2DFillNvSciSyncAttrList(nvMedia2D, waiterSyncAttrs.get(), NVMEDIA_WAITER)}; error != NVMEDIA_STATUS_OK)
{
LOG_ERR("Couldn't set NvSciSyncAttrList: %d", error);
return {};
}*/
static constexpr bool cpuWaiter{true};
static constexpr NvSciSyncAccessPerm cpuPerm{NvSciSyncAccessPerm_WaitOnly};
static constexpr NvSciSyncAttrValPrimitiveType cpuPrimType[]{
NvSciSyncAttrValPrimitiveType_Syncpoint,
NvSciSyncAttrValPrimitiveType_SysmemSemaphore,
NvSciSyncAttrValPrimitiveType_SysmemSemaphorePayload64b,
};
static auto const& gpuIds{getGpuIds()};
if(gpuIds.empty())
{
LOG_ERR("Couldn't get GPU vector.");
return {};
}
NvSciSyncAttrKeyValuePair cpuWaiterKeyValuePairs[] = {
{ NvSciSyncAttrKey_NeedCpuAccess, &cpuWaiter, sizeof(cpuWaiter) },
{ NvSciSyncAttrKey_RequiredPerm, &cpuPerm, sizeof(cpuPerm) },
{ NvSciSyncAttrKey_PrimitiveInfo, &cpuPrimType, sizeof(cpuPrimType) },
{ NvSciSyncAttrKey_GpuId, gpuIds.data(), sizeof(NvSciRmGpuId) * gpuIds.size() },
};
if(auto const error{NvSciSyncAttrListSetAttrs(waiterSyncAttrs.get(), cpuWaiterKeyValuePairs, sizeof(cpuWaiterKeyValuePairs) / sizeof(cpuWaiterKeyValuePairs))}; error != NvSciError_Success)
{
LOG_ERR("Couldn't set NvSciSyncAttrList: %d", error);
return {};
}
}
// Reconcile
std::vector<NvSciSyncAttrList> const hwSignalerAttrs{hwSignalerSyncAttrs.get(), waiterSyncAttrs.get()};
ScopedNvSciSyncAttrList hwSignalerReconciledSyncAttrs{nullptr};
{
NvSciSyncAttrList hwConflictSyncAttrs{nullptr};
NvSciSyncAttrList rawHWReconciledSyncAttrs{nullptr};
if(auto const error{NvSciSyncAttrListReconcile(hwSignalerAttrs.data(), hwSignalerAttrs.size(), &rawHWReconciledSyncAttrs, &hwConflictSyncAttrs)}; error != NvSciError_Success)
{
LOG_ERR("Couldn't reconcile HW sync obj %d", error);
if(hwConflictSyncAttrs != nullptr)
{
void* dump{};
size_t len{};
if (auto const err{NvSciSyncAttrListDebugDump(hwConflictSyncAttrs, &dump, &len)}; NvSciError_Success != err) {
LOG_ERR("NvSciSyncAttrListDebugDump failed: %d", err);
} else {
LOG_ERR("Conflicted args: %-*s", len, static_cast<char*>(dump));
}
NvSciSyncAttrListFree(hwConflictSyncAttrs);
} else {
LOG_ERR("No conflict list");
}
return {};
}
hwSignalerReconciledSyncAttrs.reset(rawHWReconciledSyncAttrs);
}
With the outcommented NvMedia2DFillNvSciSyncAttrList I get:
nvmedia: ERROR: Couldn't reconcile HW sync obj 65792 (NvSciError_ReconciliationFailed) at generateHwSciSyncAttrs():616
nvmedia: ERROR: No conflict list at generateHwSciSyncAttrs():628
But with the NvMedia2DFillNvSciSyncAttrList calls the code works without any error. Is it mandatory to call NvMedia2DFillNvSciSyncAttrList on the NvSciSyncObjs’ attribute list, so there is a special, undocumented side effect of that call? Is it possible to create NvSciSyncObjs without calling NvMedia2DFillNvSciSyncAttrList?