cmake_minimum_required(VERSION 3.20)

# ---------------------------------------------------------------------------
# wpywdlss native bridge
#
# A small C++ shim that lets the Java/Fabric side talk to NVIDIA Streamline/NGX
# over Vulkan, sharing textures with Minecraft's OpenGL context via Win32
# external memory + semaphores.
#
# Phase 0 scope: bring up a Vulkan device and PROVE the interop capabilities we
# need actually exist on this machine. No NVIDIA headers required yet -- the
# Streamline/NGX integration is added in phase 2 (see STREAMLINE_SDK_DIR below).
# ---------------------------------------------------------------------------

project(wpywdlss_bridge LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE Release)
endif()

# --- JDK for jni.h ---------------------------------------------------------
# Prefer an explicit -DJAVA_HOME=... otherwise fall back to the environment.
if(NOT DEFINED JAVA_HOME)
  if(DEFINED ENV{JAVA_HOME})
    set(JAVA_HOME "$ENV{JAVA_HOME}")
  else()
    message(FATAL_ERROR "JAVA_HOME is not set and -DJAVA_HOME= was not given")
  endif()
endif()
message(STATUS "JAVA_HOME = ${JAVA_HOME}")

# --- Vulkan headers + import library --------------------------------------
# Both are vendored/generated by tools/make_vulkan_lib.cmd; no LunarG SDK needed.
set(VULKAN_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/vulkan/include")
set(VULKAN_LIB_DIR     "${CMAKE_CURRENT_SOURCE_DIR}/third_party/vulkan/lib")

if(NOT EXISTS "${VULKAN_INCLUDE_DIR}/vulkan/vulkan.h")
  message(FATAL_ERROR "Vulkan headers missing at ${VULKAN_INCLUDE_DIR}/vulkan")
endif()
if(NOT EXISTS "${VULKAN_LIB_DIR}/vulkan-1.lib")
  message(FATAL_ERROR "vulkan-1.lib missing. Run native/tools/make_vulkan_lib.cmd first.")
endif()

# --- optional Streamline / NGX (phase 2) ----------------------------------
# Point -DSTREAMLINE_SDK_DIR=D:/Download/streamline-sdk-v2.14.1 to enable the
# DLSS code paths. Left optional so phase 0 builds without it.
set(STREAMLINE_SDK_DIR "" CACHE PATH "Path to the extracted NVIDIA Streamline SDK")

add_library(wpywdlss_bridge SHARED
  src/dlss_bridge.cpp
  src/gl_probe.cpp
)

target_include_directories(wpywdlss_bridge PRIVATE
  "${VULKAN_INCLUDE_DIR}"
  "${JAVA_HOME}/include"
  "${JAVA_HOME}/include/win32"
)

target_link_directories(wpywdlss_bridge PRIVATE "${VULKAN_LIB_DIR}")
# vulkan-1 for the compute/interop device, opengl32 for the GL side of the bridge.
target_link_libraries(wpywdlss_bridge PRIVATE vulkan-1 opengl32)

if(STREAMLINE_SDK_DIR)
  message(STATUS "Streamline SDK enabled: ${STREAMLINE_SDK_DIR}")
  target_include_directories(wpywdlss_bridge PRIVATE "${STREAMLINE_SDK_DIR}/include")
  target_compile_definitions(wpywdlss_bridge PRIVATE WPYWDLSS_HAVE_STREAMLINE=1)
else()
  message(STATUS "Streamline SDK not configured -- phase 0 (Vulkan probe) only")
endif()

target_compile_definitions(wpywdlss_bridge PRIVATE
  VK_USE_PLATFORM_WIN32_KHR
  WIN32_LEAN_AND_MEAN
  NOMINMAX
)

# The DLL is loaded from a jar at runtime, so keep it self-contained.
set_target_properties(wpywdlss_bridge PROPERTIES
  PREFIX ""
  OUTPUT_NAME "wpywdlss_bridge"
)

if(MSVC)
  target_compile_options(wpywdlss_bridge PRIVATE /W4 /permissive- /utf-8)
  target_link_options(wpywdlss_bridge PRIVATE /INCREMENTAL:NO)
endif()
