[FFmpeg-devel] [INFO]AMD D3D11 to OpenCL interop extension for NV12 and P010 textures - split planes
Mark Thompson
sw at jkqxz.net
Sun Nov 25 21:34:37 EET 2018
On 24/05/2018 15:26, Mironov, Mikhail wrote:
> AMD has published OpenCL extension which allows split D3D11 texture interoped as a single 2D image into two 2D images representing Y and UV planes.
> https://www.khronos.org/registry/OpenCL/extensions/amd/cl_amd_planar_yuv.txt
I had a go at implementing this now that it is actually visible in released drivers, but I can't get it to work.
Patch trying to implement it is below. It finds the extension and the new function correctly, but I'm stuck on the creation of the whole-texture image with clCreateFromD3D11Texture2DKHR(). The error returned is CL_INVALID_D3D11_RESOURCE_KHR (-1007), but as far as I can tell none of the documented failure cases which would return that error code apply.
$ ./ffmpeg_g.exe -report -v debug -y -hwaccel d3d11va -hwaccel_device 0 -hwaccel_output_format d3d11 -i input.mp4 -an -vf "hwmap=derive_device=opencl:mode=read,unsharp_opencl,hwdownload,format=nv12" -f null -
...
[AVHWDeviceContext @ 0000000001c0de80] Using device 1002:665f (AMD Radeon (TM) R7 360 Series).
...
[h264 @ 000000000284adc0] Format d3d11 chosen by get_format().
...
[Parsed_hwmap_0 @ 0000000002a2be00] Configure hwmap d3d11 -> opencl.
[AVHWDeviceContext @ 000000000d328500] 2 OpenCL platforms found.
[AVHWDeviceContext @ 000000000d328500] 1 OpenCL devices found on platform "Intel(R) OpenCL".
[AVHWDeviceContext @ 000000000d328500] Device Intel(R) Core(TM) i3-6300 CPU @ 3.80GHz skipped (not GPU).
[AVHWDeviceContext @ 000000000d328500] 1 OpenCL devices found on platform "AMD Accelerated Parallel Processing".
[AVHWDeviceContext @ 000000000d328500] 1.0: AMD Accelerated Parallel Processing / Bonaire
[AVHWDeviceContext @ 000000000d328500] DXVA2 to OpenCL mapping function found (clCreateFromDX9MediaSurfaceKHR).
[AVHWDeviceContext @ 000000000d328500] DXVA2 in OpenCL acquire function found (clEnqueueAcquireDX9MediaSurfacesKHR).
[AVHWDeviceContext @ 000000000d328500] DXVA2 in OpenCL release function found (clEnqueueReleaseDX9MediaSurfacesKHR).
[AVHWDeviceContext @ 000000000d328500] cl_khr_d3d11_sharing found as platform extension.
[AVHWDeviceContext @ 000000000d328500] cl_amd_planar_yuv found as device extension.
[AVHWDeviceContext @ 000000000d328500] D3D11 to OpenCL mapping function found (clCreateFromD3D11Texture2DKHR).
[AVHWDeviceContext @ 000000000d328500] D3D11 in OpenCL acquire function found (clEnqueueAcquireD3D11ObjectsKHR).
[AVHWDeviceContext @ 000000000d328500] D3D11 in OpenCL release function found (clEnqueueReleaseD3D11ObjectsKHR).
[AVHWDeviceContext @ 000000000d328500] D3D11 to OpenCL mapping on AMD function found (clGetPlaneFromImageAMD).
[AVHWFramesContext @ 0000000002c13180] Failed to create CL image from D3D texture index 0: -1007.
[Parsed_hwmap_0 @ 0000000002a2be00] Failed to create derived frames context: -5.
[Parsed_hwmap_0 @ 0000000002a2be00] Failed to configure output pad on Parsed_hwmap_0
Are there any examples of using this extension that I could compare with? Alternatively, is the source code for the CL driver available somewhere so that I can work out what that error actually means?
Thanks,
- Mark
>From 25fb98f021b1347394d56ecf4781466096616542 Mon Sep 17 00:00:00 2001
From: Mark Thompson <sw at jkqxz.net>
Date: Sun, 25 Nov 2018 16:59:24 +0000
Subject: [PATCH] hwcontext_opencl: Add support for D3D11 to OpenCL mapping on AMD
Uses cl_amd_planar_yuv.
---
libavutil/hwcontext_opencl.c | 106 ++++++++++++++++++++++++++++-------
1 file changed, 86 insertions(+), 20 deletions(-)
diff --git a/libavutil/hwcontext_opencl.c b/libavutil/hwcontext_opencl.c
index 728877553f..c745b91775 100644
--- a/libavutil/hwcontext_opencl.c
+++ b/libavutil/hwcontext_opencl.c
@@ -64,6 +64,12 @@
#if HAVE_OPENCL_D3D11
#include <CL/cl_d3d11.h>
#include "hwcontext_d3d11va.h"
+
+// From cl_amd_planar_yuv; unfortunately no header is provided.
+typedef cl_mem (*clGetPlaneFromImageAMD_fn)(cl_context context,
+ cl_mem mem,
+ cl_uint plane,
+ cl_int *errcode_ret);
#endif
#if HAVE_OPENCL_DRM_ARM
@@ -113,12 +119,17 @@ typedef struct OpenCLDeviceContext {
#if HAVE_OPENCL_D3D11
int d3d11_mapping_usable;
+ int d3d11_map_amd;
+ int d3d11_map_intel;
+
clCreateFromD3D11Texture2DKHR_fn
clCreateFromD3D11Texture2DKHR;
clEnqueueAcquireD3D11ObjectsKHR_fn
clEnqueueAcquireD3D11ObjectsKHR;
clEnqueueReleaseD3D11ObjectsKHR_fn
clEnqueueReleaseD3D11ObjectsKHR;
+ clGetPlaneFromImageAMD_fn
+ clGetPlaneFromImageAMD;
#endif
#if HAVE_OPENCL_DRM_ARM
@@ -817,17 +828,25 @@ static int opencl_device_init(AVHWDeviceContext *hwdev)
#if HAVE_OPENCL_D3D11
{
const char *d3d11_ext = "cl_khr_d3d11_sharing";
- const char *nv12_ext = "cl_intel_d3d11_nv12_media_sharing";
+ const char *amd_ext = "cl_amd_planar_yuv";
+ const char *intel_ext = "cl_intel_d3d11_nv12_media_sharing";
int fail = 0;
if (!opencl_check_extension(hwdev, d3d11_ext)) {
av_log(hwdev, AV_LOG_VERBOSE, "The %s extension is "
"required for D3D11 to OpenCL mapping.\n", d3d11_ext);
fail = 1;
- } else if (!opencl_check_extension(hwdev, nv12_ext)) {
- av_log(hwdev, AV_LOG_VERBOSE, "The %s extension may be "
- "required for D3D11 to OpenCL mapping.\n", nv12_ext);
- // Not fatal.
+ } else {
+ if (opencl_check_extension(hwdev, amd_ext)) {
+ priv->d3d11_map_amd = 1;
+ } else if (opencl_check_extension(hwdev, intel_ext)) {
+ priv->d3d11_map_intel = 1;
+ } else {
+ av_log(hwdev, AV_LOG_VERBOSE, "One of the %s or %s "
+ "extensions are required for D3D11 to OpenCL "
+ "mapping.\n", amd_ext, intel_ext);
+ fail = 1;
+ }
}
CL_FUNC(clCreateFromD3D11Texture2DKHR,
@@ -837,6 +856,11 @@ static int opencl_device_init(AVHWDeviceContext *hwdev)
CL_FUNC(clEnqueueReleaseD3D11ObjectsKHR,
"D3D11 in OpenCL release");
+ if (priv->d3d11_map_amd) {
+ CL_FUNC(clGetPlaneFromImageAMD,
+ "D3D11 to OpenCL mapping on AMD");
+ }
+
if (fail) {
av_log(hwdev, AV_LOG_WARNING, "D3D11 to OpenCL mapping "
"not usable.\n");
@@ -2573,10 +2597,22 @@ static int opencl_frames_derive_from_d3d11(AVHWFramesContext *dst_fc,
cl_int cle;
int err, i, p, nb_planes;
- if (src_fc->sw_format != AV_PIX_FMT_NV12) {
- av_log(dst_fc, AV_LOG_ERROR, "Only NV12 textures are supported "
- "for D3D11 to OpenCL mapping.\n");
- return AVERROR(EINVAL);
+ // AMD supports NV12 and P010, Intel only supports NV12.
+ if (device_priv->d3d11_map_amd) {
+ if (src_fc->sw_format != AV_PIX_FMT_NV12 &&
+ src_fc->sw_format != AV_PIX_FMT_P010) {
+ av_log(dst_fc, AV_LOG_ERROR, "Only NV12 and P010 textures are "
+ "supported with AMD for D3D11 to OpenCL mapping.\n");
+ return AVERROR(EINVAL);
+ }
+ } else if (device_priv->d3d11_map_intel) {
+ if (src_fc->sw_format != AV_PIX_FMT_NV12) {
+ av_log(dst_fc, AV_LOG_ERROR, "Only NV12 and P010 textures are "
+ "supported with Intel for D3D11 to OpenCL mapping.\n");
+ return AVERROR(EINVAL);
+ }
+ } else {
+ av_assert0(0);
}
nb_planes = 2;
@@ -2601,21 +2637,51 @@ static int opencl_frames_derive_from_d3d11(AVHWFramesContext *dst_fc,
for (i = 0; i < frames_priv->nb_mapped_frames; i++) {
AVOpenCLFrameDescriptor *desc = &frames_priv->mapped_frames[i];
desc->nb_planes = nb_planes;
- for (p = 0; p < nb_planes; p++) {
- UINT subresource = 2 * i + p;
- desc->planes[p] =
- device_priv->clCreateFromD3D11Texture2DKHR(
- dst_dev->context, cl_flags, src_hwctx->texture,
- subresource, &cle);
- if (!desc->planes[p]) {
- av_log(dst_fc, AV_LOG_ERROR, "Failed to create CL "
- "image from plane %d of D3D texture "
- "index %d (subresource %u): %d.\n",
- p, i, (unsigned int)subresource, cle);
+ if (device_priv->d3d11_map_amd) {
+ cl_mem image;
+
+ image = device_priv->clCreateFromD3D11Texture2DKHR(
+ dst_dev->context, cl_flags, src_hwctx->texture, i, &cle);
+ if (!image) {
+ av_log(dst_fc, AV_LOG_ERROR, "Failed to create CL image "
+ "from D3D texture index %d: %d.\n", i, cle);
err = AVERROR(EIO);
goto fail;
}
+
+ for (p = 0; p < nb_planes; p++) {
+ desc->planes[p] = device_priv->clGetPlaneFromImageAMD(
+ dst_dev->context, image, p, &cle);
+ if (!desc->planes[p]) {
+ av_log(dst_fc, AV_LOG_ERROR, "Failed to create CL image "
+ "from plane %d of image created from D3D11 "
+ "texture index %d: %d.\n", p, cle, i);
+ clReleaseMemObject(image);
+ err = AVERROR(EIO);
+ goto fail;
+ }
+ }
+
+ clReleaseMemObject(image);
+
+ } else {
+ for (p = 0; p < nb_planes; p++) {
+ UINT subresource = 2 * i + p;
+
+ desc->planes[p] =
+ device_priv->clCreateFromD3D11Texture2DKHR(
+ dst_dev->context, cl_flags, src_hwctx->texture,
+ subresource, &cle);
+ if (!desc->planes[p]) {
+ av_log(dst_fc, AV_LOG_ERROR, "Failed to create CL "
+ "image from plane %d of D3D texture "
+ "index %d (subresource %u): %d.\n",
+ p, i, (unsigned int)subresource, cle);
+ err = AVERROR(EIO);
+ goto fail;
+ }
+ }
}
}
--
2.19.1
More information about the ffmpeg-devel
mailing list