cmake_minimum_required(VERSION 3.21)
project(FrameGeneration LANGUAGES CXX)
add_library(framegen_core INTERFACE)
target_compile_features(framegen_core INTERFACE cxx_std_20)
target_include_directories(framegen_core INTERFACE "${CMAKE_CURRENT_LIST_DIR}/..")
option(FRAMEGEN_WITH_DLSS "Compile the standalone D3D12 Streamline adapter" OFF)
option(FRAMEGEN_WITH_FSR "Compile the standalone D3D12 FidelityFX adapter" OFF)
option(FRAMEGEN_WITH_XESS "Compile the standalone D3D12 Intel XeSS-FG adapter" OFF)
set(FRAMEGEN_STREAMLINE_INCLUDE "" CACHE PATH "Pinned Streamline v2.14.1 include directory")
set(FRAMEGEN_FIDELITYFX_INCLUDE "" CACHE PATH "Pinned FidelityFX v1.1.4 ffx-api/include directory")
set(FRAMEGEN_XESS_INCLUDE "" CACHE PATH "Intel XeSS SDK inc directory (xess_fg/ and xell/)")
if(FRAMEGEN_WITH_DLSS OR FRAMEGEN_WITH_FSR OR FRAMEGEN_WITH_XESS)
  if(NOT WIN32)
    message(FATAL_ERROR "These SDK adapters currently target Windows D3D12; the core is portable")
  endif()
  add_library(framegen_d3d12 STATIC d3d12.cpp)
  # Pinned SL 2.14.1 has a broken C++23 to_underlying alias in its public header.
  set_target_properties(framegen_d3d12 PROPERTIES CXX_STANDARD 20 CXX_STANDARD_REQUIRED YES)
  target_link_libraries(framegen_d3d12 PUBLIC framegen_core d3d12 dxgi)
  target_compile_definitions(framegen_d3d12 PUBLIC NOMINMAX)
  if(FRAMEGEN_WITH_DLSS)
    if(NOT EXISTS "${FRAMEGEN_STREAMLINE_INCLUDE}/sl_dlss_g.h")
      message(FATAL_ERROR "Streamline 2.14.1 headers required")
    endif()
    target_sources(framegen_d3d12 PRIVATE dlss_d3d12.cpp)
    target_include_directories(framegen_d3d12 SYSTEM PRIVATE "${FRAMEGEN_STREAMLINE_INCLUDE}")
    target_compile_definitions(framegen_d3d12 PUBLIC FRAMEGEN_WITH_DLSS=1)
    target_link_libraries(framegen_d3d12 PRIVATE wintrust crypt32)
  endif()
  if(FRAMEGEN_WITH_FSR)
    if(NOT EXISTS "${FRAMEGEN_FIDELITYFX_INCLUDE}/ffx_api/ffx_framegeneration.h")
      message(FATAL_ERROR "FidelityFX 1.1.4 headers required")
    endif()
    target_sources(framegen_d3d12 PRIVATE fsr_d3d12.cpp)
    target_include_directories(framegen_d3d12 SYSTEM PRIVATE "${FRAMEGEN_FIDELITYFX_INCLUDE}")
    target_compile_definitions(framegen_d3d12 PUBLIC FRAMEGEN_WITH_FSR=1)
  endif()
  if(FRAMEGEN_WITH_XESS)
    if(NOT EXISTS "${FRAMEGEN_XESS_INCLUDE}/xess_fg/xefg_swapchain_d3d12.h" OR
       NOT EXISTS "${FRAMEGEN_XESS_INCLUDE}/xell/xell_d3d12.h")
      message(FATAL_ERROR "Intel XeSS SDK headers (xess_fg, xell) required")
    endif()
    # Runtime DLLs are loaded dynamically; no import libraries are linked.
    target_sources(framegen_d3d12 PRIVATE xess_d3d12.cpp)
    target_include_directories(framegen_d3d12 SYSTEM PRIVATE "${FRAMEGEN_XESS_INCLUDE}")
    target_compile_definitions(framegen_d3d12 PUBLIC FRAMEGEN_WITH_XESS=1)
  endif()
endif()
