Fixed and updated OpenCL-VA interoperability

pull/18410/head
Odianosen Ejale 4 years ago committed by Maksim Shabunin
parent 0dc28d3446
commit 862fc06b6f
  1. 160
      3rdparty/include/opencl/1.2/CL/cl_va_api_media_sharing_intel.h
  2. 5
      CMakeLists.txt
  3. 9
      cmake/OpenCVDetectOpenCL.cmake
  4. 9
      cmake/OpenCVFindLibsVideo.cmake
  5. 5
      cmake/OpenCVFindVA.cmake
  6. 31
      cmake/OpenCVFindVA_INTEL.cmake
  7. 3
      modules/core/CMakeLists.txt
  8. 9
      modules/core/include/opencv2/core/va_intel.hpp
  9. 36
      modules/core/src/va_intel.cpp
  10. 2
      samples/CMakeLists.txt
  11. 2
      samples/va_intel/CMakeLists.txt

@ -0,0 +1,160 @@
/*******************************************************************************
* Copyright (c) 2008-2020 The Khronos Group Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
/*****************************************************************************\
Copyright (c) 2013-2019 Intel Corporation All Rights Reserved.
THESE MATERIALS ARE PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THESE
MATERIALS, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
File Name: cl_va_api_media_sharing_intel.h
Abstract:
Notes:
\*****************************************************************************/
#ifndef __OPENCL_CL_VA_API_MEDIA_SHARING_INTEL_H
#define __OPENCL_CL_VA_API_MEDIA_SHARING_INTEL_H
#include <CL/cl.h>
#include <CL/cl_platform.h>
#include <va/va.h>
#ifdef __cplusplus
extern "C" {
#endif
/******************************************
* cl_intel_va_api_media_sharing extension *
*******************************************/
#define cl_intel_va_api_media_sharing 1
/* error codes */
#define CL_INVALID_VA_API_MEDIA_ADAPTER_INTEL -1098
#define CL_INVALID_VA_API_MEDIA_SURFACE_INTEL -1099
#define CL_VA_API_MEDIA_SURFACE_ALREADY_ACQUIRED_INTEL -1100
#define CL_VA_API_MEDIA_SURFACE_NOT_ACQUIRED_INTEL -1101
/* cl_va_api_device_source_intel */
#define CL_VA_API_DISPLAY_INTEL 0x4094
/* cl_va_api_device_set_intel */
#define CL_PREFERRED_DEVICES_FOR_VA_API_INTEL 0x4095
#define CL_ALL_DEVICES_FOR_VA_API_INTEL 0x4096
/* cl_context_info */
#define CL_CONTEXT_VA_API_DISPLAY_INTEL 0x4097
/* cl_mem_info */
#define CL_MEM_VA_API_MEDIA_SURFACE_INTEL 0x4098
/* cl_image_info */
#define CL_IMAGE_VA_API_PLANE_INTEL 0x4099
/* cl_command_type */
#define CL_COMMAND_ACQUIRE_VA_API_MEDIA_SURFACES_INTEL 0x409A
#define CL_COMMAND_RELEASE_VA_API_MEDIA_SURFACES_INTEL 0x409B
typedef cl_uint cl_va_api_device_source_intel;
typedef cl_uint cl_va_api_device_set_intel;
extern CL_API_ENTRY cl_int CL_API_CALL
clGetDeviceIDsFromVA_APIMediaAdapterINTEL(
cl_platform_id platform,
cl_va_api_device_source_intel media_adapter_type,
void* media_adapter,
cl_va_api_device_set_intel media_adapter_set,
cl_uint num_entries,
cl_device_id* devices,
cl_uint* num_devices) CL_EXT_SUFFIX__VERSION_1_2;
typedef CL_API_ENTRY cl_int (CL_API_CALL * clGetDeviceIDsFromVA_APIMediaAdapterINTEL_fn)(
cl_platform_id platform,
cl_va_api_device_source_intel media_adapter_type,
void* media_adapter,
cl_va_api_device_set_intel media_adapter_set,
cl_uint num_entries,
cl_device_id* devices,
cl_uint* num_devices) CL_EXT_SUFFIX__VERSION_1_2;
extern CL_API_ENTRY cl_mem CL_API_CALL
clCreateFromVA_APIMediaSurfaceINTEL(
cl_context context,
cl_mem_flags flags,
VASurfaceID* surface,
cl_uint plane,
cl_int* errcode_ret) CL_EXT_SUFFIX__VERSION_1_2;
typedef CL_API_ENTRY cl_mem (CL_API_CALL * clCreateFromVA_APIMediaSurfaceINTEL_fn)(
cl_context context,
cl_mem_flags flags,
VASurfaceID* surface,
cl_uint plane,
cl_int* errcode_ret) CL_EXT_SUFFIX__VERSION_1_2;
extern CL_API_ENTRY cl_int CL_API_CALL
clEnqueueAcquireVA_APIMediaSurfacesINTEL(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem* mem_objects,
cl_uint num_events_in_wait_list,
const cl_event* event_wait_list,
cl_event* event) CL_EXT_SUFFIX__VERSION_1_2;
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueAcquireVA_APIMediaSurfacesINTEL_fn)(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem* mem_objects,
cl_uint num_events_in_wait_list,
const cl_event* event_wait_list,
cl_event* event) CL_EXT_SUFFIX__VERSION_1_2;
extern CL_API_ENTRY cl_int CL_API_CALL
clEnqueueReleaseVA_APIMediaSurfacesINTEL(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem* mem_objects,
cl_uint num_events_in_wait_list,
const cl_event* event_wait_list,
cl_event* event) CL_EXT_SUFFIX__VERSION_1_2;
typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueReleaseVA_APIMediaSurfacesINTEL_fn)(
cl_command_queue command_queue,
cl_uint num_objects,
const cl_mem* mem_objects,
cl_uint num_events_in_wait_list,
const cl_event* event_wait_list,
cl_event* event) CL_EXT_SUFFIX__VERSION_1_2;
#ifdef __cplusplus
}
#endif
#endif /* __OPENCL_CL_VA_API_MEDIA_SHARING_INTEL_H */

@ -1434,10 +1434,6 @@ if(WITH_VA OR HAVE_VA)
status(" VA:" HAVE_VA THEN "YES" ELSE NO) status(" VA:" HAVE_VA THEN "YES" ELSE NO)
endif() endif()
if(WITH_VA_INTEL OR HAVE_VA_INTEL)
status(" Intel VA-API/OpenCL:" HAVE_VA_INTEL THEN "YES (OpenCL: ${VA_INTEL_IOCL_ROOT})" ELSE NO)
endif()
if(WITH_TENGINE OR HAVE_TENGINE) if(WITH_TENGINE OR HAVE_TENGINE)
status(" Tengine:" HAVE_TENGINE THEN "YES (${TENGINE_LIBRARIES})" ELSE NO) status(" Tengine:" HAVE_TENGINE THEN "YES (${TENGINE_LIBRARIES})" ELSE NO)
endif() endif()
@ -1550,6 +1546,7 @@ if(WITH_OPENCL OR HAVE_OPENCL)
IF HAVE_CLAMDFFT THEN "AMDFFT" IF HAVE_CLAMDFFT THEN "AMDFFT"
IF HAVE_CLAMDBLAS THEN "AMDBLAS" IF HAVE_CLAMDBLAS THEN "AMDBLAS"
IF HAVE_OPENCL_D3D11_NV THEN "NVD3D11" IF HAVE_OPENCL_D3D11_NV THEN "NVD3D11"
IF HAVE_VA_INTEL THEN "INTELVA"
ELSE "no extra features") ELSE "no extra features")
status("") status("")
status(" OpenCL:" HAVE_OPENCL THEN "YES (${opencl_features})" ELSE "NO") status(" OpenCL:" HAVE_OPENCL THEN "YES (${opencl_features})" ELSE "NO")

@ -81,4 +81,13 @@ if(OPENCL_FOUND)
# check WITH_OPENCL_D3D11_NV is located in OpenCVDetectDirectX.cmake file # check WITH_OPENCL_D3D11_NV is located in OpenCVDetectDirectX.cmake file
if(WITH_VA_INTEL AND HAVE_VA)
if(HAVE_OPENCL AND EXISTS "${OPENCL_INCLUDE_DIR}/CL/cl_va_api_media_sharing_intel.h")
set(HAVE_VA_INTEL ON)
elseif(HAVE_OPENCL AND EXISTS "${OPENCL_INCLUDE_DIR}/CL/va_ext.h")
set(HAVE_VA_INTEL ON)
set(HAVE_VA_INTEL_OLD_HEADER ON)
endif()
endif()
endif() endif()

@ -3,15 +3,6 @@ if(WIN32)
list(APPEND HIGHGUI_LIBRARIES comctl32 gdi32 ole32 setupapi ws2_32) list(APPEND HIGHGUI_LIBRARIES comctl32 gdi32 ole32 setupapi ws2_32)
endif(WIN32) endif(WIN32)
# --- VA & VA_INTEL ---
if(WITH_VA_INTEL)
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindVA_INTEL.cmake")
if(VA_INTEL_IOCL_INCLUDE_DIR)
ocv_include_directories(${VA_INTEL_IOCL_INCLUDE_DIR})
endif()
set(WITH_VA YES)
endif(WITH_VA_INTEL)
if(WITH_VA) if(WITH_VA)
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindVA.cmake") include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindVA.cmake")
if(VA_INCLUDE_DIR) if(VA_INCLUDE_DIR)

@ -1,5 +1,6 @@
# Main variables: # Output:
# HAVE_VA for conditional compilation OpenCV with/without libva # HAVE_VA - libva is available
# HAVE_VA_INTEL - OpenCL/libva Intel interoperability extension is available
if(UNIX AND NOT ANDROID) if(UNIX AND NOT ANDROID)
find_path( find_path(

@ -1,31 +0,0 @@
# Main variables:
# VA_INTEL_IOCL_INCLUDE_DIR to use VA_INTEL
# HAVE_VA_INTEL for conditional compilation OpenCV with/without VA_INTEL
# VA_INTEL_IOCL_ROOT - root of Intel OCL installation
if(UNIX AND NOT ANDROID)
ocv_check_environment_variables(VA_INTEL_IOCL_ROOT)
if(NOT DEFINED VA_INTEL_IOCL_ROOT)
set(VA_INTEL_IOCL_ROOT "/opt/intel/opencl")
endif()
find_path(
VA_INTEL_IOCL_INCLUDE_DIR
NAMES CL/va_ext.h
PATHS ${VA_INTEL_IOCL_ROOT}
PATH_SUFFIXES include
DOC "Path to Intel OpenCL headers")
endif()
if(VA_INTEL_IOCL_INCLUDE_DIR)
set(HAVE_VA_INTEL TRUE)
if(NOT DEFINED VA_INTEL_LIBRARIES)
set(VA_INTEL_LIBRARIES "va" "va-drm")
endif()
else()
set(HAVE_VA_INTEL FALSE)
message(WARNING "Intel OpenCL installation is not found.")
endif()
mark_as_advanced(FORCE VA_INTEL_IOCL_INCLUDE_DIR)

@ -80,6 +80,9 @@ endif()
if(HAVE_MEMALIGN) if(HAVE_MEMALIGN)
ocv_append_source_file_compile_definitions(${CMAKE_CURRENT_SOURCE_DIR}/src/alloc.cpp "HAVE_MEMALIGN=1") ocv_append_source_file_compile_definitions(${CMAKE_CURRENT_SOURCE_DIR}/src/alloc.cpp "HAVE_MEMALIGN=1")
endif() endif()
if(HAVE_VA_INTEL_OLD_HEADER)
ocv_append_source_file_compile_definitions("${CMAKE_CURRENT_LIST_DIR}/src/va_intel.cpp" "HAVE_VA_INTEL_OLD_HEADER")
endif()
option(OPENCV_ENABLE_ALLOCATOR_STATS "Enable Allocator metrics" ON) option(OPENCV_ENABLE_ALLOCATOR_STATS "Enable Allocator metrics" ON)

@ -29,14 +29,11 @@ namespace cv { namespace va_intel {
/** @addtogroup core_va_intel /** @addtogroup core_va_intel
This section describes Intel VA-API/OpenCL (CL-VA) interoperability. This section describes Intel VA-API/OpenCL (CL-VA) interoperability.
To enable CL-VA interoperability support, configure OpenCV using CMake with WITH_VA_INTEL=ON . Currently VA-API is To enable basic VA interoperability build OpenCV with libva library integration enabled: `-DWITH_VA=ON` (corresponding dev package should be installed).
supported on Linux only. You should also install Intel Media Server Studio (MSS) to use this feature. You may
have to specify the path(s) to MSS components for cmake in environment variables:
- VA_INTEL_IOCL_ROOT for Intel OpenCL (default is "/opt/intel/opencl"). To enable advanced CL-VA interoperability support on Intel HW, enable option: `-DWITH_VA_INTEL=ON` (OpenCL integration should be enabled which is the default setting). Special runtime environment should be set up in order to use this feature: correct combination of [libva](https://github.com/intel/libva), [OpenCL runtime](https://github.com/intel/compute-runtime) and [media driver](https://github.com/intel/media-driver) should be installed.
To use CL-VA interoperability you should first create VADisplay (libva), and then call initializeContextFromVA() Check usage example for details: samples/va_intel/va_intel_interop.cpp
function to create OpenCL context and set up interoperability.
*/ */
//! @{ //! @{

@ -25,13 +25,17 @@ using namespace cv;
# include "opencl_kernels_core.hpp" # include "opencl_kernels_core.hpp"
#endif // HAVE_OPENCL #endif // HAVE_OPENCL
#if defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL) #ifdef HAVE_VA_INTEL
#ifdef HAVE_VA_INTEL_OLD_HEADER
# include <CL/va_ext.h> # include <CL/va_ext.h>
#endif // HAVE_VA_INTEL && HAVE_OPENCL #else
# include <CL/cl_va_api_media_sharing_intel.h>
#endif
#endif
namespace cv { namespace va_intel { namespace cv { namespace va_intel {
#if defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL) #ifdef HAVE_VA_INTEL
static clGetDeviceIDsFromVA_APIMediaAdapterINTEL_fn clGetDeviceIDsFromVA_APIMediaAdapterINTEL = NULL; static clGetDeviceIDsFromVA_APIMediaAdapterINTEL_fn clGetDeviceIDsFromVA_APIMediaAdapterINTEL = NULL;
static clCreateFromVA_APIMediaSurfaceINTEL_fn clCreateFromVA_APIMediaSurfaceINTEL = NULL; static clCreateFromVA_APIMediaSurfaceINTEL_fn clCreateFromVA_APIMediaSurfaceINTEL = NULL;
@ -40,7 +44,7 @@ static clEnqueueReleaseVA_APIMediaSurfacesINTEL_fn clEnqueueReleaseVA_APIMediaS
static bool contextInitialized = false; static bool contextInitialized = false;
#endif // HAVE_VA_INTEL && HAVE_OPENCL #endif // HAVE_VA_INTEL
namespace ocl { namespace ocl {
@ -50,7 +54,7 @@ Context& initializeContextFromVA(VADisplay display, bool tryInterop)
#if !defined(HAVE_VA) #if !defined(HAVE_VA)
NO_VA_SUPPORT_ERROR; NO_VA_SUPPORT_ERROR;
#else // !HAVE_VA #else // !HAVE_VA
# if (defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL)) # ifdef HAVE_VA_INTEL
contextInitialized = false; contextInitialized = false;
if (tryInterop) if (tryInterop)
{ {
@ -137,7 +141,13 @@ Context& initializeContextFromVA(VADisplay display, bool tryInterop)
contextInitialized = true; contextInitialized = true;
cl_platform_id platform = platforms[found]; cl_platform_id platform = platforms[found];
std::string platformName = PlatformInfo(platform).name(); char platformName[1024] = {0};
size_t sz = 0;
if (clGetPlatformInfo(platform, CL_PLATFORM_NAME, sizeof(platformName) - 16, platformName, &sz) != CL_SUCCESS
|| sz >= sizeof(platformName))
{
CV_Error(cv::Error::OpenCLInitError, "OpenCL: Failed to get platform name");
}
OpenCLExecutionContext clExecCtx; OpenCLExecutionContext clExecCtx;
try try
@ -154,7 +164,7 @@ Context& initializeContextFromVA(VADisplay display, bool tryInterop)
return const_cast<Context&>(clExecCtx.getContext()); return const_cast<Context&>(clExecCtx.getContext());
} }
} }
# endif // HAVE_VA_INTEL && HAVE_OPENCL # endif // HAVE_VA_INTEL
{ {
Context& ctx = Context::getDefault(true); Context& ctx = Context::getDefault(true);
return ctx; return ctx;
@ -162,7 +172,7 @@ Context& initializeContextFromVA(VADisplay display, bool tryInterop)
#endif // !HAVE_VA #endif // !HAVE_VA
} }
#if defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL) #ifdef HAVE_VA_INTEL
static bool ocl_convert_nv12_to_bgr(cl_mem clImageY, cl_mem clImageUV, cl_mem clBuffer, int step, int cols, int rows) static bool ocl_convert_nv12_to_bgr(cl_mem clImageY, cl_mem clImageUV, cl_mem clBuffer, int step, int cols, int rows)
{ {
ocl::Kernel k; ocl::Kernel k;
@ -188,7 +198,7 @@ static bool ocl_convert_bgr_to_nv12(cl_mem clBuffer, int step, int cols, int row
size_t globalsize[] = { (size_t)cols, (size_t)rows }; size_t globalsize[] = { (size_t)cols, (size_t)rows };
return k.run(2, globalsize, 0, false); return k.run(2, globalsize, 0, false);
} }
#endif // HAVE_VA_INTEL && HAVE_OPENCL #endif // HAVE_VA_INTEL
} // namespace cv::va_intel::ocl } // namespace cv::va_intel::ocl
@ -511,7 +521,7 @@ void convertToVASurface(VADisplay display, InputArray src, VASurfaceID surface,
Size srcSize = src.size(); Size srcSize = src.size();
CV_Assert(srcSize.width == size.width && srcSize.height == size.height); CV_Assert(srcSize.width == size.width && srcSize.height == size.height);
# if (defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL)) #ifdef HAVE_VA_INTEL
if (contextInitialized) if (contextInitialized)
{ {
UMat u = src.getUMat(); UMat u = src.getUMat();
@ -559,7 +569,7 @@ void convertToVASurface(VADisplay display, InputArray src, VASurfaceID surface,
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed (UV plane)"); CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed (UV plane)");
} }
else else
# endif // HAVE_VA_INTEL && HAVE_OPENCL # endif // HAVE_VA_INTEL
{ {
Mat m = src.getMat(); Mat m = src.getMat();
@ -612,7 +622,7 @@ void convertFromVASurface(VADisplay display, VASurfaceID surface, Size size, Out
// TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying! // TODO Need to specify ACCESS_WRITE here somehow to prevent useless data copying!
dst.create(size, dtype); dst.create(size, dtype);
# if (defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL)) #ifdef HAVE_VA_INTEL
if (contextInitialized) if (contextInitialized)
{ {
UMat u = dst.getUMat(); UMat u = dst.getUMat();
@ -660,7 +670,7 @@ void convertFromVASurface(VADisplay display, VASurfaceID surface, Size size, Out
CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed (UV plane)"); CV_Error(cv::Error::OpenCLApiCallError, "OpenCL: clReleaseMem failed (UV plane)");
} }
else else
# endif // HAVE_VA_INTEL && HAVE_OPENCL # endif // HAVE_VA_INTEL
{ {
Mat m = dst.getMat(); Mat m = dst.getMat();

@ -36,7 +36,7 @@ endif()
if(HAVE_OPENVX) if(HAVE_OPENVX)
add_subdirectory(openvx) add_subdirectory(openvx)
endif() endif()
if(UNIX AND NOT ANDROID AND (HAVE_VA OR HAVE_VA_INTEL)) if(UNIX AND NOT ANDROID AND HAVE_VA)
add_subdirectory(va_intel) add_subdirectory(va_intel)
endif() endif()
if(ANDROID AND (BUILD_ANDROID_EXAMPLES OR INSTALL_ANDROID_EXAMPLES)) if(ANDROID AND (BUILD_ANDROID_EXAMPLES OR INSTALL_ANDROID_EXAMPLES))

@ -17,5 +17,5 @@ ocv_include_modules_recurse(${OPENCV_VA_INTEL_SAMPLES_REQUIRED_DEPS})
file(GLOB all_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) file(GLOB all_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp)
foreach(sample_filename ${all_samples}) foreach(sample_filename ${all_samples})
ocv_define_sample(tgt ${sample_filename} va_intel) ocv_define_sample(tgt ${sample_filename} va_intel)
ocv_target_link_libraries(${tgt} PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_VA_INTEL_SAMPLES_REQUIRED_DEPS} ${VA_LIBRARIES} ${VA_INTEL_LIBRARIES}) ocv_target_link_libraries(${tgt} PRIVATE ${OPENCV_LINKER_LIBS} ${OPENCV_VA_INTEL_SAMPLES_REQUIRED_DEPS} ${VA_LIBRARIES})
endforeach() endforeach()

Loading…
Cancel
Save