# compiler choose,now support ICC,GCC CLANG compiler
if (COMPILER STREQUAL "GCC")
  find_program(CMAKE_C_COMPILER NAMES gcc)
  find_program(CMAKE_CXX_COMPILER NAMES g++)
elseif (COMPILER STREQUAL "CLANG")
  set (CMAKE_C_COMPILER   "clang")
  set (CMAKE_CXX_COMPILER "clang++")
  find_program(CMAKE_AR NAMES llvm-ar)
  find_program(CMAKE_LINKER NAMES llvm-ld)
elseif (COMPILER STREQUAL "ICC")
  find_program(CMAKE_C_COMPILER NAMES icc)
  find_program(CMAKE_CXX_COMPILER NAMES icpc)
  find_program(CMAKE_AR NAMES xiar)
  find_program(CMAKE_LINKER NAMES xild)
endif ()

CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0)
PROJECT(OCL)
if( ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
  set(COMPILER "CLANG")
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
  set(COMPILER "GCC")
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")
  set(COMPILER "ICC")
endif()
set (NOT_BUILD_STAND_ALONE_UTEST 1)

INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
                    ${CMAKE_CURRENT_SOURCE_DIR}/include)


INCLUDE (FindPkgConfig)

SET(CMAKE_VERBOSE_MAKEFILE "false")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMake/")
INCLUDE (GNUInstallDirs OPTIONAL)
# support old CMake without GNUInstallDirs
if (NOT CMAKE_INSTALL_FULL_LIBDIR)
  set (CMAKE_INSTALL_FULL_LIBDIR "${CMAKE_INSTALL_PREFIX}/lib")
  set (BEIGNET_LIBRARY_ARCHITECTURE "")
else (NOT CMAKE_INSTALL_FULL_LIBDIR)
  set (BEIGNET_LIBRARY_ARCHITECTURE "${CMAKE_LIBRARY_ARCHITECTURE}")
endif (NOT CMAKE_INSTALL_FULL_LIBDIR)

if (NOT LIB_INSTALL_DIR)
  set (LIB_INSTALL_DIR "${CMAKE_INSTALL_FULL_LIBDIR}")
endif (NOT LIB_INSTALL_DIR)
if (NOT BEIGNET_INSTALL_DIR)
  set (BEIGNET_INSTALL_DIR "${LIB_INSTALL_DIR}/beignet/")
endif (NOT BEIGNET_INSTALL_DIR)

# allow co-installation of 32- and 64-bit versions:
# https://wiki.debian.org/Multiarch
if (BEIGNET_INSTALL_DIR STREQUAL "${CMAKE_INSTALL_PREFIX}/lib/beignet/")
  set (ICD_FILE_NAME "intel-beignet.icd")
else (BEIGNET_INSTALL_DIR STREQUAL "${CMAKE_INSTALL_PREFIX}/lib/beignet/")
  if (BEIGNET_LIBRARY_ARCHITECTURE STREQUAL "")
    set (ICD_FILE_NAME "intel-beignet.icd")
  else (BEIGNET_LIBRARY_ARCHITECTURE STREQUAL "")
    set (ICD_FILE_NAME "intel-beignet-${BEIGNET_LIBRARY_ARCHITECTURE}.icd")
  endif (BEIGNET_LIBRARY_ARCHITECTURE STREQUAL "")
endif (BEIGNET_INSTALL_DIR STREQUAL "${CMAKE_INSTALL_PREFIX}/lib/beignet/")

# Force Release with debug info
if (NOT CMAKE_BUILD_TYPE)
  set (CMAKE_BUILD_TYPE RelWithDebInfo)
endif (NOT CMAKE_BUILD_TYPE)
set (CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "assure config" FORCE)
message(STATUS "Building mode: " ${CMAKE_BUILD_TYPE})

# XXX now hard coded to enable the clamp to border workaround for IVB.
ADD_DEFINITIONS(-DGEN7_SAMPLER_CLAMP_BORDER_WORKAROUND)

# compiler flag setting
if (COMPILER STREQUAL "GCC")
  set (CMAKE_C_CXX_FLAGS "${CMAKE_C_CXX_FLAGS} -funroll-loops -fstrict-aliasing -msse2 -msse3 -mssse3 -msse4.1 -fPIC -Wall -mfpmath=sse -Wcast-align -Wl,-E")
elseif (COMPILER STREQUAL "CLANG")
  set (CMAKE_C_CXX_FLAGS "${CMAKE_C_CXX_FLAGS} -funroll-loops -fstrict-aliasing -msse2 -msse3 -mssse3 -msse4.1 -fPIC -Wall")
elseif (COMPILER STREQUAL "ICC")
  set (CMAKE_C_CXX_FLAGS "${CMAKE_C_CXX_FLAGS}  -wd2928 -Wall -fPIC -fstrict-aliasing -fp-model fast -msse4.1 -Wl,-E")
endif ()
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_CXX_FLAGS} -std=c++0x -Wno-invalid-offsetof")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_CXX_FLAGS}")
set (CMAKE_CXX_FLAGS_DEBUG          "-O0 -g -DGBE_DEBUG=1")
set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DGBE_DEBUG=1")
set (CMAKE_CXX_FLAGS_MINSIZEREL     "-Os -DNDEBUG -DGBE_DEBUG=0")
set (CMAKE_CXX_FLAGS_RELEASE        "-O2 -DNDEBUG -DGBE_DEBUG=0")
set (CMAKE_C_FLAGS_DEBUG          "-O0 -g -DGBE_DEBUG=1")
set (CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g -DGBE_DEBUG=1")
set (CMAKE_C_FLAGS_MINSIZEREL     "-Os -DNDEBUG -DGBE_DEBUG=0")
set (CMAKE_C_FLAGS_RELEASE        "-O2 -DNDEBUG -DGBE_DEBUG=0")


IF (USE_STANDALONE_GBE_COMPILER STREQUAL "true")
  Find_Package(StandaloneGbeCompiler)
ELSE (USE_STANDALONE_GBE_COMPILER STREQUAL "true")
  # Front end stuff we need
  #INCLUDE(CMake/FindLLVM.cmake)
  Find_Package(LLVM 3.3)
  SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
ENDIF (USE_STANDALONE_GBE_COMPILER STREQUAL "true")


set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-Bsymbolic -Wl,--no-undefined ${LLVM_LDFLAGS}")

# XLib
Find_Package(X11)
IF(X11_FOUND)
  MESSAGE(STATUS "Looking for XLib - found")
ELSE(X11_FOUND)
  MESSAGE(STATUS "Looking for XLib - not found")
ENDIF(X11_FOUND)

# DRM
pkg_check_modules(DRM REQUIRED libdrm)
IF(DRM_FOUND)
  MESSAGE(STATUS "Looking for DRM - found at ${DRM_PREFIX} ${DRM_VERSION}")
  INCLUDE_DIRECTORIES(${DRM_INCLUDE_DIRS})
ELSE(DRM_FOUND)
  MESSAGE(STATUS "Looking for DRM - not found")
ENDIF(DRM_FOUND)

include(CheckLibraryExists)
# DRM Intel
pkg_check_modules(DRM_INTEL libdrm_intel>=2.4.52)
IF(DRM_INTEL_FOUND)
  INCLUDE_DIRECTORIES(${DRM_INTEL_INCLUDE_DIRS})
  MESSAGE(STATUS "Looking for DRM Intel - found at ${DRM_INTEL_PREFIX} ${DRM_INTEL_VERSION}")
  CHECK_LIBRARY_EXISTS(drm_intel "drm_intel_bo_alloc_userptr" ${DRM_INTEL_LIBDIR} HAVE_DRM_INTEL_USERPTR)
  IF(HAVE_DRM_INTEL_USERPTR)
    MESSAGE(STATUS "Enable userptr support")
  ELSE(HAVE_DRM_INTEL_USERPTR)
    MESSAGE(STATUS "Disable userptr support")
  ENDIF(HAVE_DRM_INTEL_USERPTR)
  CHECK_LIBRARY_EXISTS(drm_intel "drm_intel_get_eu_total" ${DRM_INTEL_LIBDIR} HAVE_DRM_INTEL_EU_TOTAL)
  IF(HAVE_DRM_INTEL_EU_TOTAL)
    MESSAGE(STATUS "Enable EU total query support")
  ELSE(HAVE_DRM_INTEL_EU_TOTAL)
    MESSAGE(STATUS "Disable EU total query support")
  ENDIF(HAVE_DRM_INTEL_EU_TOTAL)
  CHECK_LIBRARY_EXISTS(drm_intel "drm_intel_get_subslice_total" ${DRM_INTEL_LIBDIR} HAVE_DRM_INTEL_SUBSLICE_TOTAL)
  IF(HAVE_DRM_INTEL_SUBSLICE_TOTAL)
    MESSAGE(STATUS "Enable subslice total query support")
  ELSE(HAVE_DRM_INTEL_SUBSLICE_TOTAL)
    MESSAGE(STATUS "Disable subslice total query support")
  ENDIF(HAVE_DRM_INTEL_SUBSLICE_TOTAL)
  CHECK_LIBRARY_EXISTS(drm_intel "drm_intel_get_pooled_eu" ${DRM_INTEL_LIBDIR} HAVE_DRM_INTEL_POOLED_EU)
  IF(HAVE_DRM_INTEL_POOLED_EU)
    MESSAGE(STATUS "Enable pooled eu query support")
  ELSE(HAVE_DRM_INTEL_POOLED_EU)
    MESSAGE(STATUS "Disable pooled eu query support")
  ENDIF(HAVE_DRM_INTEL_POOLED_EU)
  CHECK_LIBRARY_EXISTS(drm_intel "drm_intel_get_min_eu_in_pool" ${DRM_INTEL_LIBDIR} HAVE_DRM_INTEL_MIN_EU_IN_POOL)
  IF(HAVE_DRM_INTEL_MIN_EU_IN_POOL)
    MESSAGE(STATUS "Enable min eu in pool query support")
  ELSE(HAVE_DRM_INTEL_MIN_EU_IN_POOL)
    MESSAGE(STATUS "Disable min eu in pool query support")
  ENDIF(HAVE_DRM_INTEL_MIN_EU_IN_POOL)
  CHECK_LIBRARY_EXISTS(drm_intel "drm_intel_bo_set_softpin_offset" ${DRM_INTEL_LIBDIR} HAVE_DRM_INTEL_BO_SET_SOFTPIN)
ELSE(DRM_INTEL_FOUND)
  MESSAGE(FATAL_ERROR "Looking for DRM Intel (>= 2.4.52) - not found")
ENDIF(DRM_INTEL_FOUND)

# CMRT
#disable CMRT as default, since we do not see real case,
#but see build issue of this feature
OPTION(INVOKE_CMRT "Enable CMRT" OFF)
IF(INVOKE_CMRT)
pkg_check_modules(CMRT libcmrt)
IF(CMRT_FOUND)
INCLUDE_DIRECTORIES(${CMRT_INCLUDE_DIRS})
ENDIF(CMRT_FOUND)
ENDIF(INVOKE_CMRT)

# Threads
Find_Package(Threads)

IF(X11_FOUND)
# Xext
pkg_check_modules(XEXT REQUIRED xext)
IF(XEXT_FOUND)
  INCLUDE_DIRECTORIES(${XEXT_INCLUDE_DIRS})
  MESSAGE(STATUS "Looking for Xext - found at ${XEXT_PREFIX}")
ELSE(XEXT_FOUND)
  MESSAGE(STATUS "Looking for Xext - not found")
ENDIF(XEXT_FOUND)

# Xfixes
pkg_check_modules(XFIXES REQUIRED xfixes)
IF(XFIXES_FOUND)
  INCLUDE_DIRECTORIES(${XFIXES_INCLUDE_DIRS})
  MESSAGE(STATUS "Looking for Xfixes - found at ${XFIXES_PREFIX}")
ELSE(XFIXES_FOUND)
  MESSAGE(STATUS "Looking for Xfixes - not found")
ENDIF(XFIXES_FOUND)
ENDIF(X11_FOUND)

pkg_check_modules(OPENGL QUIET gl>=13.0.0)
IF(OPENGL_FOUND)
  MESSAGE(STATUS "Looking for OpenGL - found at ${OPENGL_PREFIX} ${OPENGL_VERSION}")
ELSE(OPENGL_FOUND)
  MESSAGE(STATUS "Looking for OpenGL (>=13.0.0) - not found, cl_khr_gl_sharing will be disabled")
ENDIF(OPENGL_FOUND)
pkg_check_modules(EGL QUIET egl>=13.0.0)
IF(EGL_FOUND)
  MESSAGE(STATUS "Looking for EGL - found at ${EGL_PREFIX} ${EGL_VERSION}")
ELSE(EGL_FOUND)
  MESSAGE(STATUS "Looking for EGL (>=13.0.0) - not found, cl_khr_gl_sharing will be disabled")
ENDIF(EGL_FOUND)

OPTION(OCLICD_COMPAT "OCL ICD compatibility mode" ON)
IF(OCLICD_COMPAT)
Find_Package(OCLIcd)
IF(OCLIcd_FOUND)
  MESSAGE(STATUS "Looking for OCL ICD header file - found")
  configure_file (
    "intel-beignet.icd.in"
    "${ICD_FILE_NAME}"
  )
  install (FILES ${CMAKE_CURRENT_BINARY_DIR}/${ICD_FILE_NAME} DESTINATION /etc/OpenCL/vendors)
ELSE(OCLIcd_FOUND)
  MESSAGE(STATUS "Looking for OCL ICD header file - not found")
  MESSAGE(FATAL_ERROR "OCL ICD loader miss. If you really want to disable OCL ICD support, please run cmake with option -DOCLICD_COMPAT=0.")
ENDIF(OCLIcd_FOUND)
ENDIF(OCLICD_COMPAT)

Find_Package(PythonInterp)

OPTION(EXPERIMENTAL_DOUBLE "Enable experimental double support" OFF)
IF (EXPERIMENTAL_DOUBLE)
  ADD_DEFINITIONS(-DENABLE_FP64)
ENDIF(EXPERIMENTAL_DOUBLE)

SET(CAN_OPENCL_20 ON)
IF (CMAKE_SIZEOF_VOID_P EQUAL 4)
  SET(CAN_OPENCL_20 OFF)
ENDIF (CMAKE_SIZEOF_VOID_P EQUAL 4)
IF (NOT HAVE_DRM_INTEL_BO_SET_SOFTPIN)
  SET(CAN_OPENCL_20 OFF)
ENDIF (NOT HAVE_DRM_INTEL_BO_SET_SOFTPIN)
IF (LLVM_VERSION_NODOT VERSION_LESS 39)
  SET(CAN_OPENCL_20 OFF)
ENDIF (LLVM_VERSION_NODOT VERSION_LESS 39)

IF (ENABLE_OPENCL_20)
  IF (NOT HAVE_DRM_INTEL_BO_SET_SOFTPIN)
    MESSAGE(FATAL_ERROR "Please update libdrm to version 2.4.66 or later to enable OpenCL 2.0.")
  ENDIF (NOT HAVE_DRM_INTEL_BO_SET_SOFTPIN)

  IF (LLVM_VERSION_NODOT VERSION_LESS 39)
    MESSAGE(FATAL_ERROR "Please update LLVM to version 3.9 or later to enable OpenCL 2.0.")
  ENDIF (LLVM_VERSION_NODOT VERSION_LESS 39)

  IF (CMAKE_SIZEOF_VOID_P EQUAL 4)
    MESSAGE(FATAL_ERROR "Please use x64 host to enable OpenCL 2.0.")
  ENDIF (CMAKE_SIZEOF_VOID_P EQUAL 4)
ENDIF(ENABLE_OPENCL_20)

IF (DEFINED ENABLE_OPENCL_20)
  IF (ENABLE_OPENCL_20 AND CAN_OPENCL_20)
    SET(CAN_OPENCL_20 ON)
  ELSE(ENABLE_OPENCL_20 AND CAN_OPENCL_20)
    SET(CAN_OPENCL_20 OFF)
  ENDIF (ENABLE_OPENCL_20 AND CAN_OPENCL_20)
ENDIF (DEFINED ENABLE_OPENCL_20)

OPTION(ENABLE_OPENCL_20 "Enable opencl 2.0 support" ${CAN_OPENCL_20})

IF (CAN_OPENCL_20)
  SET (ENABLE_OPENCL_20 ON)
  MESSAGE(STATUS "Building with OpenCL 2.0.")
  ADD_DEFINITIONS(-DENABLE_OPENCL_20)
ELSE (CAN_OPENCL_20)
  MESSAGE(STATUS "Building with OpenCL 1.2.")
ENDIF(CAN_OPENCL_20)

set (LIBCL_DRIVER_VERSION_MAJOR 1)
set (LIBCL_DRIVER_VERSION_MINOR 3)
set (LIBCL_DRIVER_VERSION_PATCH 2)
if (ENABLE_OPENCL_20)
  set (LIBCL_C_VERSION_MAJOR 2)
  set (LIBCL_C_VERSION_MINOR 0)
else (ENABLE_OPENCL_20)
  set (LIBCL_C_VERSION_MAJOR 1)
  set (LIBCL_C_VERSION_MINOR 2)
endif (ENABLE_OPENCL_20)
configure_file (
  "src/OCLConfig.h.in"
  "src/OCLConfig.h"
)


OPTION(BUILD_EXAMPLES "Build examples" OFF)
IF(BUILD_EXAMPLES)
IF(NOT X11_FOUND)
  MESSAGE(FATAL_ERROR "XLib is necessary for examples - not found")
ENDIF(NOT X11_FOUND)

# libva & libva-x11
pkg_check_modules(LIBVA REQUIRED libva)
pkg_check_modules(LIBVA-X11 REQUIRED libva-x11)
set(LIBVA_BUF_SH_DEP false)
set(V4L2_BUF_SH_DEP false)
IF(LIBVA_FOUND AND LIBVA-X11_FOUND)
  MESSAGE(STATUS "Looking for LIBVA - found at ${LIBVA_PREFIX} ${LIBVA_VERSION}")
  MESSAGE(STATUS "Looking for LIBVA-X11 - found at ${LIBVA-X11_PREFIX} ${LIBVA-X11_VERSION}")
  INCLUDE_DIRECTORIES(${LIBVA_INCLUDE_DIRS})
  INCLUDE_DIRECTORIES(${LIBVA-X11_INCLUDE_DIRS})
  set(V4L2_BUF_SH_DEP true)
  IF(LIBVA_VERSION VERSION_LESS "0.36.0" OR LIBVA-X11_VERSION VERSION_LESS "0.36.0")
    IF(LIBVA_VERSION VERSION_LESS "0.36.0")
      MESSAGE(STATUS "Looking for LIBVA (>= 0.36.0) - not found")
    ENDIF(LIBVA_VERSION VERSION_LESS "0.36.0")
    IF(LIBVA-X11_VERSION VERSION_LESS "0.36.0")
      MESSAGE(STATUS "Looking for LIBVA-X11 (>= 0.36.0) - not found")
    ENDIF(LIBVA-X11_VERSION VERSION_LESS "0.36.0")
    MESSAGE(STATUS "Example libva_buffer_sharing will not be built")
  ELSE(LIBVA_VERSION VERSION_LESS "0.36.0" OR LIBVA-X11_VERSION VERSION_LESS "0.36.0")
    set(LIBVA_BUF_SH_DEP true)
  ENDIF(LIBVA_VERSION VERSION_LESS "0.36.0" OR LIBVA-X11_VERSION VERSION_LESS "0.36.0")
ELSE(LIBVA_FOUND AND LIBVA-X11_FOUND)
  MESSAGE(STATUS "Example libva_buffer_sharing and v4l2_buffer_sharing will not be built")
ENDIF(LIBVA_FOUND AND LIBVA-X11_FOUND)
IF(NOT (OPENGL_FOUND AND EGL_FOUND AND X11_FOUND))
  MESSAGE(STATUS "Example gl_buffer_sharing will not be built")
ENDIF(NOT (OPENGL_FOUND AND EGL_FOUND AND X11_FOUND))
ENDIF(BUILD_EXAMPLES)

ADD_SUBDIRECTORY(include)
ADD_SUBDIRECTORY(backend)
ADD_SUBDIRECTORY(src)
ADD_SUBDIRECTORY(utests EXCLUDE_FROM_ALL)

# compile benchmark only if standalone compiler is not provided
IF (NOT (USE_STANDALONE_GBE_COMPILER STREQUAL "true"))
  ADD_SUBDIRECTORY(benchmark EXCLUDE_FROM_ALL)
ENDIF (NOT (USE_STANDALONE_GBE_COMPILER STREQUAL "true"))

IF(BUILD_EXAMPLES)
ADD_SUBDIRECTORY(examples)
ENDIF(BUILD_EXAMPLES)

SET(CPACK_SET_DESTDIR ON)
SET(CPACK_PACKAGE_VERSION_MAJOR "${LIBCL_DRIVER_VERSION_MAJOR}")
SET(CPACK_PACKAGE_VERSION_MINOR "${LIBCL_DRIVER_VERSION_MINOR}")
SET(CPACK_PACKAGE_VERSION_PATCH "${LIBCL_DRIVER_VERSION_PATCH}")
SET(CPACK_SOURCE_GENERATOR "TGZ;TZ")
SET(CPACK_PACKAGE_NAME "Beignet")
SET(CPACK_PACKAGE_VENDOR "Intel Open Source Technology Center")
INCLUDE(CPack)
