cmake_minimum_required(VERSION 3.20)
project(srw64_pixel_gpu_test LANGUAGES C CXX)
include(CTest)
get_filename_component(ROOT "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE)
set(SRW64_RT64_HEADERS "" CACHE PATH "Pinned RT64 source with Plume/DXC submodules")
option(SRW64_PIXEL_TEST_WARP "Allow the real D3D12 software adapter in this isolated test only" OFF)
if(NOT EXISTS "${SRW64_RT64_HEADERS}/src/contrib/plume/plume_render_interface.h")
    message(FATAL_ERROR "SRW64_RT64_HEADERS must contain the pinned Plume source")
endif()
set(PLUME_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(PLUME_SDL_VULKAN_ENABLED OFF CACHE BOOL "" FORCE)
add_subdirectory("${SRW64_RT64_HEADERS}/src/contrib/plume" plume)
add_subdirectory("${SRW64_RT64_HEADERS}/src/tools/file_to_c" file-to-c)
if(APPLE)
    target_link_libraries(plume PUBLIC "-framework Metal" "-framework Foundation" "-framework QuartzCore" "-framework Cocoa" "-framework IOKit")
    # Same pinned converter as the game, without its tool CMake's global output overrides.
    set(SPIRV_CROSS_CLI OFF CACHE BOOL "" FORCE)
    set(SPIRV_CROSS_ENABLE_TESTS OFF CACHE BOOL "" FORCE)
    add_subdirectory("${SRW64_RT64_HEADERS}/src/contrib/spirv-cross" spirv-cross EXCLUDE_FROM_ALL)
    add_executable(spirv_cross_msl "${SRW64_RT64_HEADERS}/src/tools/spirv_cross_msl/spirv_cross_msl.cpp")
    target_compile_features(spirv_cross_msl PRIVATE cxx_std_17)
    target_link_libraries(spirv_cross_msl PRIVATE spirv-cross-core spirv-cross-msl)
    target_include_directories(spirv_cross_msl PRIVATE "${SRW64_RT64_HEADERS}/src/contrib/spirv-cross")
    # The pristine upstream binary-shader path, not the game's source-shader patch.
    set(SRW64_METAL_SOURCE_SHADERS OFF)
elseif(WIN32)
    target_link_libraries(plume PUBLIC d3d12 dxgi dxguid)
    if(SRW64_PIXEL_TEST_WARP)
        find_package(Python3 3.11 COMPONENTS Interpreter REQUIRED)
        set(warp_source "${CMAKE_CURRENT_BINARY_DIR}/plume_d3d12_software.cpp")
        execute_process(COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/prepare_warp.py"
            --source "${SRW64_RT64_HEADERS}/src/contrib/plume/plume_d3d12.cpp" --output "${warp_source}"
            COMMAND_ERROR_IS_FATAL ANY)
        get_target_property(plume_sources plume SOURCES)
        list(FILTER plume_sources EXCLUDE REGEX "(^|/)plume_d3d12\\.cpp$")
        set_property(TARGET plume PROPERTY SOURCES ${plume_sources} "${warp_source}")
    endif()
else()
    find_package(X11 REQUIRED)
    # Attach requirements to the static library that uses them, so GNU ld sees
    # X11 AFTER libplume rather than discarding it early with --as-needed.
    target_link_libraries(plume PUBLIC ${CMAKE_DL_LIBS} ${X11_LIBRARIES} ${X11_Xrandr_LIB})
endif()
include("${ROOT}/cmake/PixelCompositor.cmake")
srw64_add_pixel_compositor("${SRW64_RT64_HEADERS}")
add_executable(srw64-pixel-gpu-test gpu.cpp)
target_link_libraries(srw64-pixel-gpu-test PRIVATE srw64_pixel_compositor)
target_compile_features(srw64-pixel-gpu-test PRIVATE cxx_std_20)
# Diagnostic startup only; it does not replace rendering, fence or pixel checks.
target_sources(srw64-pixel-gpu-test PRIVATE test_startup.cpp)
# The game's dialogue adapter compiles against the same compositor on every platform.
add_library(srw64-dialogue-plume-compile OBJECT "${ROOT}/src/host/dialogue_plume.cpp")
target_link_libraries(srw64-dialogue-plume-compile PRIVATE srw64_pixel_compositor)
target_include_directories(srw64-dialogue-plume-compile PRIVATE "${ROOT}/src/host" "${SRW64_RT64_HEADERS}/src/contrib")
if(APPLE)
    target_include_directories(srw64-pixel-gpu-test PRIVATE "${SRW64_RT64_HEADERS}/src/contrib/plume/contrib/metal-cpp")
    target_compile_options(srw64-pixel-gpu-test PRIVATE -fblocks)
    target_include_directories(srw64-dialogue-plume-compile PRIVATE "${SRW64_RT64_HEADERS}/src/contrib/plume/contrib/metal-cpp")
    target_compile_options(srw64-dialogue-plume-compile PRIVATE -fblocks)
elseif(WIN32)
    target_compile_definitions(srw64-pixel-gpu-test PRIVATE NOMINMAX)
    target_link_libraries(srw64-pixel-gpu-test PRIVATE dbghelp)
    target_compile_options(plume PRIVATE /Zi)
    target_link_options(srw64-pixel-gpu-test PRIVATE /DEBUG)
endif()
add_test(NAME pixel-gpu COMMAND srw64-pixel-gpu-test)
set_tests_properties(pixel-gpu PROPERTIES TIMEOUT 120)
