cmake_minimum_required(VERSION 3.22)
project(malig925_repro)

# =============================================================================
#  Compute shader: repro.comp → SPIR-V → embedded C header
#
#  Requires glslc (ships with the Vulkan SDK).
#    Linux:   sudo apt install vulkan-tools  OR  https://vulkan.lunarg.com/
#    Windows: Vulkan SDK installer adds glslc to PATH automatically.
#
#  If glslc is not on PATH, set the VULKAN_SDK environment variable to the
#  SDK root (e.g. /home/user/VulkanSDK/1.3.290.0/x86_64).
#
#  Manual fallback (run once from app/src/main/cpp/):
#    glslc repro.comp -o repro_comp.spv
#    cmake -DINPUT=repro_comp.spv -DOUTPUT=repro_comp_spv.h -P embed_spv.cmake
# =============================================================================

find_program(GLSLC glslc
    HINTS
        # NDK bundles glslc in shader-tools/ (NDK r23+)
        "${CMAKE_ANDROID_NDK}/shader-tools/windows-x86_64"
        "${CMAKE_ANDROID_NDK}/shader-tools/linux-x86_64"
        "${CMAKE_ANDROID_NDK}/shader-tools/darwin-x86_64"
        "$ENV{VULKAN_SDK}/bin"
        "$ENV{VULKAN_SDK}/Bin"   # Windows Vulkan SDK layout
    PATH_SUFFIXES bin)
if(NOT GLSLC)
    find_program(GLSLC glslc)   # PATH fallback
endif()
if(NOT GLSLC)
    message(FATAL_ERROR
        "glslc not found.\n"
        "Install the Vulkan SDK: https://vulkan.lunarg.com/sdk/home\n"
        "Then set VULKAN_SDK or add the SDK bin/ dir to PATH.\n"
        "Manual fallback:\n"
        "  glslc repro.comp -o repro_comp.spv\n"
        "  cmake -DINPUT=repro_comp.spv -DOUTPUT=repro_comp_spv.h -P embed_spv.cmake")
endif()
message(STATUS "glslc: ${GLSLC}")

set(COMP_SRC "${CMAKE_CURRENT_SOURCE_DIR}/repro.comp")
# SPV named repro_comp_spv.spv so embed_spv.cmake derives variable name
# "repro_comp_spv", matching repro.cpp's repro_comp_spv[] / repro_comp_spv_len.
set(COMP_SPV "${CMAKE_CURRENT_BINARY_DIR}/repro_comp_spv.spv")
set(COMP_HDR "${CMAKE_CURRENT_BINARY_DIR}/repro_comp_spv.h")

add_custom_command(
    OUTPUT  "${COMP_SPV}"
    COMMAND "${GLSLC}" "${COMP_SRC}" -o "${COMP_SPV}"
    DEPENDS "${COMP_SRC}"
    COMMENT "glslc: repro.comp → repro_comp.spv")

add_custom_command(
    OUTPUT  "${COMP_HDR}"
    COMMAND "${CMAKE_COMMAND}"
            "-DINPUT=${COMP_SPV}"
            "-DOUTPUT=${COMP_HDR}"
            "-P" "${CMAKE_CURRENT_SOURCE_DIR}/embed_spv.cmake"
    DEPENDS "${COMP_SPV}" "${CMAKE_CURRENT_SOURCE_DIR}/embed_spv.cmake"
    COMMENT "embed: repro_comp.spv → repro_comp_spv.h")

add_custom_target(gen_shader_header DEPENDS "${COMP_HDR}")

# =============================================================================
#  NativeActivity shared library
# =============================================================================

add_library(malig925_repro SHARED
    repro.cpp
    "${CMAKE_ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c")

add_dependencies(malig925_repro gen_shader_header)

target_include_directories(malig925_repro PRIVATE
    "${CMAKE_CURRENT_BINARY_DIR}"                               # repro_comp_spv.h
    "${CMAKE_ANDROID_NDK}/sources/android/native_app_glue")

# SYNC_MODE: SYNC_WAIT_SEMAPHORES (1) | SYNC_GET_COUNTER (2) |
#            SYNC_WAIT_FENCES (3)     | SYNC_QUEUE_WAIT_IDLE (4)
# Override via app/build.gradle: cmake { arguments '-DSYNC_MODE=SYNC_WAIT_FENCES' }
if(NOT DEFINED SYNC_MODE)
    set(SYNC_MODE SYNC_WAIT_SEMAPHORES)
endif()
target_compile_definitions(malig925_repro PRIVATE
    SYNC_MODE=${SYNC_MODE}
    VK_USE_PLATFORM_ANDROID_KHR)   # exposes VkAndroidSurfaceCreateInfoKHR / vkCreateAndroidSurfaceKHR

# -std=c++17 must not be passed to the C file (android_native_app_glue.c)
target_compile_options(malig925_repro PRIVATE
    $<$<COMPILE_LANGUAGE:CXX>:-std=c++17>
    -O2 -Wall)
target_link_libraries(malig925_repro android log vulkan)
