cmake_minimum_required(VERSION 3.24)
project(mag_render_native LANGUAGES C CXX)
set(MAG_RENDER_NATIVE_BACKEND "none" CACHE STRING "Frontend-owned native backend")
add_library(mag_render_native_impl STATIC native/mag_render_native.c native/mag_render_scene_validate.c native/mag_render_stencil_validate.c native/mag_render_image_validate.c native/mag_render_raster_validate.c native/mag_render_sampler_validate.c native/mag_render_sampler_registry.c native/mag_render_native_api.cpp native/mag_render_packet_api.cpp)
target_include_directories(mag_render_native_impl PUBLIC native)
target_compile_features(mag_render_native_impl PRIVATE c_std_11 cxx_std_17)
if(MSVC)
    target_compile_options(mag_render_native_impl PRIVATE /W4 /WX "$<$<COMPILE_LANGUAGE:CXX>:/EHsc>")
else()
    target_compile_options(mag_render_native_impl PRIVATE -Wall -Wextra -Werror)
endif()
if(MAG_RENDER_NATIVE_BACKEND STREQUAL "metal")
    if(NOT APPLE)
        message(FATAL_ERROR "Metal requires macOS")
    endif()
    enable_language(OBJC)
    target_sources(mag_render_native_impl PRIVATE native/mag_render_metal.m)
    target_compile_definitions(mag_render_native_impl PRIVATE MAG_RENDER_NATIVE_METAL)
    target_compile_options(mag_render_native_impl PRIVATE "$<$<COMPILE_LANGUAGE:OBJC>:-fobjc-arc>")
elseif(MAG_RENDER_NATIVE_BACKEND STREQUAL "vulkan")
    target_sources(mag_render_native_impl PRIVATE native/mag_render_vulkan.c)
    target_compile_definitions(mag_render_native_impl PRIVATE MAG_RENDER_NATIVE_VULKAN)
    if(WIN32)
        # Opt-in on Windows: headers only, from an explicit directory. Entry points come
        # from the host's own loader through the owner's proc-address functions.
        find_path(MAG_RENDER_VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h
            HINTS ENV MAG_RENDER_VULKAN_INCLUDE_DIR REQUIRED)
        target_include_directories(mag_render_native_impl PRIVATE ${MAG_RENDER_VULKAN_INCLUDE_DIR})
        # The backend reads its opt-in switches with getenv, as on Linux.
        target_compile_definitions(mag_render_native_impl PRIVATE _CRT_SECURE_NO_WARNINGS)
    else()
        find_package(PkgConfig REQUIRED)
        pkg_check_modules(VULKAN_HEADERS REQUIRED vulkan)
        target_include_directories(mag_render_native_impl PRIVATE ${VULKAN_HEADERS_INCLUDE_DIRS})
        target_compile_options(mag_render_native_impl PRIVATE ${VULKAN_HEADERS_CFLAGS_OTHER})
    endif()
elseif(MAG_RENDER_NATIVE_BACKEND STREQUAL "d3d12")
    if(NOT WIN32)
        message(FATAL_ERROR "D3D12 requires Windows")
    endif()
    # The DXC library itself is loaded from an explicit absolute runtime path.
    # Only the pinned compiler API header is a build dependency; no dxcompiler
    # or d3d12 import library/device discovery is added to the frontend.
    find_path(MAG_RENDER_DXC_INCLUDE_DIR NAMES dxcapi.h
        HINTS ENV MAG_RENDER_DXC_INCLUDE_DIR REQUIRED)
    target_sources(mag_render_native_impl PRIVATE native/mag_render_d3d12.cpp native/mag_render_dxc.cpp)
    target_compile_definitions(mag_render_native_impl PRIVATE MAG_RENDER_NATIVE_D3D12)
    target_include_directories(mag_render_native_impl PRIVATE ${MAG_RENDER_DXC_INCLUDE_DIR})
elseif(NOT MAG_RENDER_NATIVE_BACKEND STREQUAL "none")
    message(FATAL_ERROR "Unknown native backend")
endif()
