goto exit;
}
- ret = CHECK_CU(cu->cuStreamSynchronize(hwctx->stream));
- if (ret < 0)
- goto exit;
-
exit:
CHECK_CU(cu->cuCtxPopCurrent(&dummy));
if (hwctx->internal) {
CudaFunctions *cu = hwctx->internal->cuda_dl;
+
if (hwctx->internal->is_allocated && hwctx->cuda_ctx) {
- CHECK_CU(cu->cuCtxDestroy(hwctx->cuda_ctx));
+ if (hwctx->internal->flags & AV_CUDA_USE_PRIMARY_CONTEXT)
+ CHECK_CU(cu->cuDevicePrimaryCtxRelease(hwctx->internal->cuda_device));
+ else
+ CHECK_CU(cu->cuCtxDestroy(hwctx->cuda_ctx));
+
hwctx->cuda_ctx = NULL;
}
+
cuda_free_functions(&hwctx->internal->cuda_dl);
}
{
AVCUDADeviceContext *hwctx = device_ctx->hwctx;
CudaFunctions *cu;
- CUdevice cu_device;
CUcontext dummy;
- int ret, device_idx = 0;
+ int ret, dev_active = 0, device_idx = 0;
+ unsigned int dev_flags = 0;
+
+ const unsigned int desired_flags = CU_CTX_SCHED_BLOCKING_SYNC;
if (device)
device_idx = strtol(device, NULL, 0);
if (ret < 0)
goto error;
- ret = CHECK_CU(cu->cuDeviceGet(&cu_device, device_idx));
+ ret = CHECK_CU(cu->cuDeviceGet(&hwctx->internal->cuda_device, device_idx));
if (ret < 0)
goto error;
- ret = CHECK_CU(cu->cuCtxCreate(&hwctx->cuda_ctx, CU_CTX_SCHED_BLOCKING_SYNC, cu_device));
- if (ret < 0)
- goto error;
+ hwctx->internal->flags = flags;
- // Setting stream to NULL will make functions automatically use the default CUstream
- hwctx->stream = NULL;
+ if (flags & AV_CUDA_USE_PRIMARY_CONTEXT) {
+ ret = CHECK_CU(cu->cuDevicePrimaryCtxGetState(hwctx->internal->cuda_device, &dev_flags, &dev_active));
+ if (ret < 0)
+ goto error;
- CHECK_CU(cu->cuCtxPopCurrent(&dummy));
+ if (dev_active && dev_flags != desired_flags) {
+ av_log(device_ctx, AV_LOG_ERROR, "Primary context already active with incompatible flags.\n");
+ goto error;
+ } else if (dev_flags != desired_flags) {
+ ret = CHECK_CU(cu->cuDevicePrimaryCtxSetFlags(hwctx->internal->cuda_device, desired_flags));
+ if (ret < 0)
+ goto error;
+ }
+
+ ret = CHECK_CU(cu->cuDevicePrimaryCtxRetain(&hwctx->cuda_ctx, hwctx->internal->cuda_device));
+ if (ret < 0)
+ goto error;
+ } else {
+ ret = CHECK_CU(cu->cuCtxCreate(&hwctx->cuda_ctx, desired_flags, hwctx->internal->cuda_device));
+ if (ret < 0)
+ goto error;
+
+ CHECK_CU(cu->cuCtxPopCurrent(&dummy));
+ }
hwctx->internal->is_allocated = 1;
+ // Setting stream to NULL will make functions automatically use the default CUstream
+ hwctx->stream = NULL;
+
return 0;
error: