cmake_minimum_required(VERSION 3.22)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
project(EldenCraftCompositor VERSION 0.1.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
enable_testing()
add_executable(frame_protocol_test tests/frame_protocol_test.cpp)
target_include_directories(frame_protocol_test PRIVATE include)
add_test(NAME frame_protocol COMMAND frame_protocol_test)
add_executable(scene_protocol_test tests/scene_protocol_test.cpp)
target_include_directories(scene_protocol_test PRIVATE include)
add_test(NAME scene_protocol COMMAND scene_protocol_test)
add_executable(block_protocol_test tests/block_protocol_test.cpp)
target_include_directories(block_protocol_test PRIVATE include)
add_test(NAME block_protocol COMMAND block_protocol_test)
add_executable(block_residency_test tests/block_residency_test.cpp)
target_include_directories(block_residency_test PRIVATE include)
add_test(NAME block_residency COMMAND block_residency_test)
add_executable(block_sort_test tests/block_sort_test.cpp)
target_include_directories(block_sort_test PRIVATE include)
add_test(NAME block_sort COMMAND block_sort_test)
add_executable(nether_protocol_test tests/nether_protocol_test.cpp)
target_include_directories(nether_protocol_test PRIVATE include)
add_test(NAME nether_protocol COMMAND nether_protocol_test)
add_executable(gpu_transport_test tests/gpu_transport_test.cpp)
target_include_directories(gpu_transport_test PRIVATE include)
add_test(NAME gpu_transport COMMAND gpu_transport_test)
if(WIN32)
    if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
        message(FATAL_ERROR "Only Windows x64 is supported")
    endif()
    set(RESHADE_INCLUDE_DIR "" CACHE PATH "ReShade v6.8.0 include directory")
    if(NOT EXISTS "${RESHADE_INCLUDE_DIR}/reshade.hpp")
        message(FATAL_ERROR "Set RESHADE_INCLUDE_DIR to headers from ReShade v6.8.0 (18deaa52de0c425a78b329e9cb3c497281cd00ec)")
    endif()
    add_library(EldenCraftCompositor SHARED src/addon.cpp src/block_renderer.cpp src/gpu_host.cpp src/scene_mask.cpp)
    target_link_libraries(EldenCraftCompositor PRIVATE d3dcompiler)
    add_executable(block_shader_test tests/block_shader_test.cpp)
    target_include_directories(block_shader_test PRIVATE include)
    target_link_libraries(block_shader_test PRIVATE d3dcompiler)
    add_test(NAME block_shader COMMAND block_shader_test)
    add_executable(gpu_shared_test tests/gpu_shared_test.cpp)
    target_link_libraries(gpu_shared_test PRIVATE d3d12 dxgi)
    add_test(NAME gpu_shared COMMAND gpu_shared_test)
    add_executable(d3d12_bindings_test tests/d3d12_bindings_test.cpp)
    target_include_directories(d3d12_bindings_test PRIVATE include "${RESHADE_INCLUDE_DIR}")
    target_compile_definitions(d3d12_bindings_test PRIVATE WIN32_LEAN_AND_MEAN NOMINMAX RESHADE_API_LIBRARY=1)
    target_link_libraries(d3d12_bindings_test PRIVATE d3d12 dxgi d3dcompiler)
    add_test(NAME d3d12_bindings COMMAND d3d12_bindings_test)
    add_executable(block_lighting_test tests/block_lighting_test.cpp)
    target_include_directories(block_lighting_test PRIVATE include)
    target_link_libraries(block_lighting_test PRIVATE d3d11 d3dcompiler)
    add_test(NAME block_lighting COMMAND block_lighting_test)
    add_executable(scene_projection_test tests/scene_projection_test.cpp)
    target_compile_definitions(scene_projection_test PRIVATE NOMINMAX
        EC_SCENE_SHADER_PATH="${CMAKE_CURRENT_SOURCE_DIR}/shaders/EldenCraftPassthrough.fx")
    target_link_libraries(scene_projection_test PRIVATE d3d11 d3dcompiler)
    add_test(NAME scene_projection COMMAND scene_projection_test)
    add_executable(scene_mask_test tests/scene_mask_test.cpp)
    target_include_directories(scene_mask_test PRIVATE include)
    target_compile_definitions(scene_mask_test PRIVATE NOMINMAX EC_SCENE_SHADER_PATH="${CMAKE_CURRENT_SOURCE_DIR}/shaders/EldenCraftPassthrough.fx")
    target_link_libraries(scene_mask_test PRIVATE d3d11 d3dcompiler)
    add_test(NAME scene_mask COMMAND scene_mask_test)
    add_executable(nether_rules_test tests/nether_rules_test.cpp)
    target_compile_definitions(nether_rules_test PRIVATE NOMINMAX
        EC_SCENE_SHADER_PATH="${CMAKE_CURRENT_SOURCE_DIR}/shaders/EldenCraftPassthrough.fx")
    target_link_libraries(nether_rules_test PRIVATE d3d11 d3dcompiler)
    add_test(NAME nether_rules COMMAND nether_rules_test)
    add_executable(block_mapping_test tests/block_mapping_test.cpp)
    target_include_directories(block_mapping_test PRIVATE include)
    target_compile_definitions(block_mapping_test PRIVATE WIN32_LEAN_AND_MEAN NOMINMAX)
    add_test(NAME block_mapping COMMAND block_mapping_test)
    add_executable(frame_mapping_test tests/frame_mapping_test.cpp)
    target_include_directories(frame_mapping_test PRIVATE include)
    target_compile_definitions(frame_mapping_test PRIVATE WIN32_LEAN_AND_MEAN NOMINMAX)
    add_test(NAME frame_mapping COMMAND frame_mapping_test)
    target_include_directories(EldenCraftCompositor PRIVATE include "${RESHADE_INCLUDE_DIR}")
    target_compile_definitions(EldenCraftCompositor PRIVATE WIN32_LEAN_AND_MEAN NOMINMAX)
    set_target_properties(EldenCraftCompositor PROPERTIES PREFIX "" SUFFIX ".addon64")
    set_property(TARGET EldenCraftCompositor APPEND PROPERTY LINK_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/shaders/EldenCraftPassthrough.fx")
    add_executable(frame_inspect src/frame_inspect.cpp)
    target_include_directories(frame_inspect PRIVATE include)
    target_compile_definitions(frame_inspect PRIVATE WIN32_LEAN_AND_MEAN NOMINMAX)
    if(MSVC)
        # /Brepro: no timestamps, so the same toolchain rebuilds a byte-identical add-on.
        target_compile_options(EldenCraftCompositor PRIVATE /W4 /EHsc /Brepro)
        target_link_options(EldenCraftCompositor PRIVATE /Brepro)
        target_compile_options(frame_inspect PRIVATE /W4 /EHsc)
    endif()
    add_custom_command(TARGET EldenCraftCompositor POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different
        "${CMAKE_CURRENT_SOURCE_DIR}/shaders/EldenCraftPassthrough.fx" "$<TARGET_FILE_DIR:EldenCraftCompositor>/EldenCraftPassthrough.fx")
endif()
