diff --git a/3rdparty/include/opencl/1.2/CL/cl_va_api_media_sharing_intel.h b/3rdparty/include/opencl/1.2/CL/cl_va_api_media_sharing_intel.h new file mode 100644 index 0000000000..0e7cd4d6f8 --- /dev/null +++ b/3rdparty/include/opencl/1.2/CL/cl_va_api_media_sharing_intel.h @@ -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 +#include +#include + +#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 */ + diff --git a/CMakeLists.txt b/CMakeLists.txt index 386c6e21c1..4350b2fe2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1434,10 +1434,6 @@ if(WITH_VA OR HAVE_VA) status(" VA:" HAVE_VA THEN "YES" ELSE NO) 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) status(" Tengine:" HAVE_TENGINE THEN "YES (${TENGINE_LIBRARIES})" ELSE NO) endif() @@ -1550,6 +1546,7 @@ if(WITH_OPENCL OR HAVE_OPENCL) IF HAVE_CLAMDFFT THEN "AMDFFT" IF HAVE_CLAMDBLAS THEN "AMDBLAS" IF HAVE_OPENCL_D3D11_NV THEN "NVD3D11" + IF HAVE_VA_INTEL THEN "INTELVA" ELSE "no extra features") status("") status(" OpenCL:" HAVE_OPENCL THEN "YES (${opencl_features})" ELSE "NO") diff --git a/cmake/OpenCVDetectOpenCL.cmake b/cmake/OpenCVDetectOpenCL.cmake index 5349d12b69..6ab2cae070 100644 --- a/cmake/OpenCVDetectOpenCL.cmake +++ b/cmake/OpenCVDetectOpenCL.cmake @@ -81,4 +81,13 @@ if(OPENCL_FOUND) # 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() diff --git a/cmake/OpenCVFindLibsVideo.cmake b/cmake/OpenCVFindLibsVideo.cmake index 5436c4cf48..a4e52e13cf 100644 --- a/cmake/OpenCVFindLibsVideo.cmake +++ b/cmake/OpenCVFindLibsVideo.cmake @@ -3,15 +3,6 @@ if(WIN32) list(APPEND HIGHGUI_LIBRARIES comctl32 gdi32 ole32 setupapi ws2_32) 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) include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindVA.cmake") if(VA_INCLUDE_DIR) diff --git a/cmake/OpenCVFindVA.cmake b/cmake/OpenCVFindVA.cmake index 37e916d1fd..9d0ceec2c5 100644 --- a/cmake/OpenCVFindVA.cmake +++ b/cmake/OpenCVFindVA.cmake @@ -1,5 +1,6 @@ -# Main variables: -# HAVE_VA for conditional compilation OpenCV with/without libva +# Output: +# HAVE_VA - libva is available +# HAVE_VA_INTEL - OpenCL/libva Intel interoperability extension is available if(UNIX AND NOT ANDROID) find_path( diff --git a/cmake/OpenCVFindVA_INTEL.cmake b/cmake/OpenCVFindVA_INTEL.cmake deleted file mode 100644 index fcee37eb89..0000000000 --- a/cmake/OpenCVFindVA_INTEL.cmake +++ /dev/null @@ -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) diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index 59273a3a6b..73e7f1d7bb 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -80,6 +80,9 @@ endif() if(HAVE_MEMALIGN) ocv_append_source_file_compile_definitions(${CMAKE_CURRENT_SOURCE_DIR}/src/alloc.cpp "HAVE_MEMALIGN=1") 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) diff --git a/modules/core/include/opencv2/core/va_intel.hpp b/modules/core/include/opencv2/core/va_intel.hpp index f66547093e..b37ce75135 100644 --- a/modules/core/include/opencv2/core/va_intel.hpp +++ b/modules/core/include/opencv2/core/va_intel.hpp @@ -29,14 +29,11 @@ namespace cv { namespace va_intel { /** @addtogroup core_va_intel 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 -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: +To enable basic VA interoperability build OpenCV with libva library integration enabled: `-DWITH_VA=ON` (corresponding dev package should be installed). -- 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() -function to create OpenCL context and set up interoperability. +Check usage example for details: samples/va_intel/va_intel_interop.cpp */ //! @{ diff --git a/modules/core/src/va_intel.cpp b/modules/core/src/va_intel.cpp index 42948dc457..1fd574ba01 100644 --- a/modules/core/src/va_intel.cpp +++ b/modules/core/src/va_intel.cpp @@ -25,13 +25,17 @@ using namespace cv; # include "opencl_kernels_core.hpp" #endif // HAVE_OPENCL -#if defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL) +#ifdef HAVE_VA_INTEL +#ifdef HAVE_VA_INTEL_OLD_HEADER # include -#endif // HAVE_VA_INTEL && HAVE_OPENCL +#else +# include +#endif +#endif 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 clCreateFromVA_APIMediaSurfaceINTEL_fn clCreateFromVA_APIMediaSurfaceINTEL = NULL; @@ -40,7 +44,7 @@ static clEnqueueReleaseVA_APIMediaSurfacesINTEL_fn clEnqueueReleaseVA_APIMediaS static bool contextInitialized = false; -#endif // HAVE_VA_INTEL && HAVE_OPENCL +#endif // HAVE_VA_INTEL namespace ocl { @@ -50,7 +54,7 @@ Context& initializeContextFromVA(VADisplay display, bool tryInterop) #if !defined(HAVE_VA) NO_VA_SUPPORT_ERROR; #else // !HAVE_VA -# if (defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL)) +# ifdef HAVE_VA_INTEL contextInitialized = false; if (tryInterop) { @@ -137,7 +141,13 @@ Context& initializeContextFromVA(VADisplay display, bool tryInterop) contextInitialized = true; 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; try @@ -154,7 +164,7 @@ Context& initializeContextFromVA(VADisplay display, bool tryInterop) return const_cast(clExecCtx.getContext()); } } -# endif // HAVE_VA_INTEL && HAVE_OPENCL +# endif // HAVE_VA_INTEL { Context& ctx = Context::getDefault(true); return ctx; @@ -162,7 +172,7 @@ Context& initializeContextFromVA(VADisplay display, bool tryInterop) #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) { 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 }; return k.run(2, globalsize, 0, false); } -#endif // HAVE_VA_INTEL && HAVE_OPENCL +#endif // HAVE_VA_INTEL } // namespace cv::va_intel::ocl @@ -511,7 +521,7 @@ void convertToVASurface(VADisplay display, InputArray src, VASurfaceID surface, Size srcSize = src.size(); CV_Assert(srcSize.width == size.width && srcSize.height == size.height); -# if (defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL)) +#ifdef HAVE_VA_INTEL if (contextInitialized) { 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)"); } else -# endif // HAVE_VA_INTEL && HAVE_OPENCL +# endif // HAVE_VA_INTEL { 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! dst.create(size, dtype); -# if (defined(HAVE_VA_INTEL) && defined(HAVE_OPENCL)) +#ifdef HAVE_VA_INTEL if (contextInitialized) { 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)"); } else -# endif // HAVE_VA_INTEL && HAVE_OPENCL +# endif // HAVE_VA_INTEL { Mat m = dst.getMat(); diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index a542b2fb53..0c70698ccb 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -36,7 +36,7 @@ endif() if(HAVE_OPENVX) add_subdirectory(openvx) 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) endif() if(ANDROID AND (BUILD_ANDROID_EXAMPLES OR INSTALL_ANDROID_EXAMPLES)) diff --git a/samples/va_intel/CMakeLists.txt b/samples/va_intel/CMakeLists.txt index 0e56951302..c95a5ed5d5 100644 --- a/samples/va_intel/CMakeLists.txt +++ b/samples/va_intel/CMakeLists.txt @@ -17,5 +17,5 @@ ocv_include_modules_recurse(${OPENCV_VA_INTEL_SAMPLES_REQUIRED_DEPS}) file(GLOB all_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) foreach(sample_filename ${all_samples}) 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()