cmake_minimum_required(VERSION 3.31)
project(BuzzVulkanBringup LANGUAGES C CXX)
include(CTest)
get_filename_component(BUZZ_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../.." ABSOLUTE)
add_executable(buzz_texture_layout_test "${BUZZ_ROOT}/ps3recomp/libs/video/tests/test_texture_layout.c"
    "${BUZZ_ROOT}/ps3recomp/libs/video/rsx_texture_layout.c")
target_include_directories(buzz_texture_layout_test PRIVATE "${BUZZ_ROOT}/ps3recomp/include" "${BUZZ_ROOT}/ps3recomp/libs/video")
set_target_properties(buzz_texture_layout_test PROPERTIES C_STANDARD 17 C_STANDARD_REQUIRED ON)
add_test(NAME texture-fast-rows-reference COMMAND buzz_texture_layout_test)
set_tests_properties(texture-fast-rows-reference PROPERTIES TIMEOUT 45)
add_executable(buzz_vertex_fetch_test "${BUZZ_ROOT}/ps3recomp/libs/video/tests/test_vertex_fetch_plan.c"
    "${BUZZ_ROOT}/ps3recomp/libs/video/rsx_vertex_compact.c" "${BUZZ_ROOT}/ps3recomp/libs/video/rsx_dispatch.c")
target_include_directories(buzz_vertex_fetch_test PRIVATE "${BUZZ_ROOT}/ps3recomp/include" "${BUZZ_ROOT}/ps3recomp/libs/video")
set_target_properties(buzz_vertex_fetch_test PROPERTIES C_STANDARD 17 C_STANDARD_REQUIRED ON)
add_test(NAME vertex-bulk-fetch-reference COMMAND buzz_vertex_fetch_test)
set_tests_properties(vertex-bulk-fetch-reference PROPERTIES TIMEOUT 45)
add_executable(buzz_rsx_engine_test "${BUZZ_ROOT}/ps3recomp/libs/video/tests/test_rsx_draw_engine.c")
foreach(source rsx_draw_engine rsx_dispatch rsx_vertex_compact rsx_texture_layout rsx_texture_pack rsx_vp_decompiler rsx_fp_decompiler)
    target_sources(buzz_rsx_engine_test PRIVATE "${BUZZ_ROOT}/ps3recomp/libs/video/${source}.c")
endforeach()
target_sources(buzz_rsx_engine_test PRIVATE "${BUZZ_ROOT}/ps3recomp/libs/system/host_controls.c")
foreach(size 1 3 64 512)
    add_test(NAME vulkan-draw-async-${size} COMMAND buzz_vulkan_batch_test ${size})
    set_tests_properties(vulkan-draw-async-${size} PROPERTIES TIMEOUT 45 ENVIRONMENT "PS3RECOMP_VK_DRAW_RING=1;PS3RECOMP_VK_DRAW_PASSES=1;PS3RECOMP_VK_DRAW_CLEARS=1;PS3RECOMP_VK_DRAW_ASYNC=1;PS3RECOMP_VK_GPU_TIMESTAMPS=0")
endforeach()
add_test(NAME vulkan-async-timestamps-rejected COMMAND buzz_vulkan_batch_test --invalid-async-timestamps)
set_tests_properties(vulkan-async-timestamps-rejected PROPERTIES TIMEOUT 10)
add_test(NAME vulkan-texture-reuse-rejected COMMAND buzz_vulkan_batch_test --invalid-texture-reuse)
set_tests_properties(vulkan-texture-reuse-rejected PROPERTIES TIMEOUT 10)
add_test(NAME vulkan-depth-format-rejected COMMAND buzz_vulkan_batch_test --invalid-depth-format)
set_tests_properties(vulkan-depth-format-rejected PROPERTIES TIMEOUT 10)
add_test(NAME vulkan-d24-reference COMMAND buzz_vulkan_batch_test 0)
set_tests_properties(vulkan-d24-reference PROPERTIES TIMEOUT 45 ENVIRONMENT "PS3RECOMP_VK_DEPTH_FORMAT=d24;PS3RECOMP_VK_DRAW_ASYNC=0")
add_test(NAME vulkan-d24-async COMMAND buzz_vulkan_batch_test 512)
set_tests_properties(vulkan-d24-async PROPERTIES TIMEOUT 45 ENVIRONMENT "PS3RECOMP_VK_DEPTH_FORMAT=d24;PS3RECOMP_VK_DRAW_RING=1;PS3RECOMP_VK_DRAW_PASSES=1;PS3RECOMP_VK_DRAW_CLEARS=1;PS3RECOMP_VK_DRAW_ASYNC=1;PS3RECOMP_VK_GPU_TIMESTAMPS=0")
add_test(NAME vulkan-d16-reference COMMAND buzz_vulkan_batch_test 0)
set_tests_properties(vulkan-d16-reference PROPERTIES TIMEOUT 45 ENVIRONMENT "PS3RECOMP_VK_DEPTH_FORMAT=d16;PS3RECOMP_VK_DRAW_ASYNC=0")
set_tests_properties(vulkan-d24-reference vulkan-d24-async PROPERTIES
    SKIP_REGULAR_EXPRESSION "requested depth format unavailable: d24")
set_tests_properties(vulkan-d16-reference PROPERTIES
    SKIP_REGULAR_EXPRESSION "requested depth format unavailable: d16")
add_test(NAME vulkan-texture-reuse-sync COMMAND buzz_vulkan_batch_test 0)
set_tests_properties(vulkan-texture-reuse-sync PROPERTIES TIMEOUT 45 ENVIRONMENT "PS3RECOMP_VK_TEXTURE_REUSE=1;PS3RECOMP_VK_DRAW_ASYNC=0")
add_test(NAME vulkan-texture-reuse-async COMMAND buzz_vulkan_batch_test 512)
set_tests_properties(vulkan-texture-reuse-async PROPERTIES TIMEOUT 45 ENVIRONMENT "PS3RECOMP_VK_TEXTURE_REUSE=1;PS3RECOMP_VK_DRAW_RING=1;PS3RECOMP_VK_DRAW_PASSES=1;PS3RECOMP_VK_DRAW_CLEARS=1;PS3RECOMP_VK_DRAW_ASYNC=1;PS3RECOMP_VK_GPU_TIMESTAMPS=0")
target_include_directories(buzz_rsx_engine_test PRIVATE "${BUZZ_ROOT}/ps3recomp/include" "${BUZZ_ROOT}/ps3recomp/libs/video")
set_target_properties(buzz_rsx_engine_test PROPERTIES C_STANDARD 17 C_STANDARD_REQUIRED ON)
add_test(NAME shared-engine-reference COMMAND buzz_rsx_engine_test)
set_tests_properties(shared-engine-reference PROPERTIES TIMEOUT 45 ENVIRONMENT "PS3RECOMP_ENG_VERTEX_BULK=0")
add_test(NAME shared-engine-bulk COMMAND buzz_rsx_engine_test)
set_tests_properties(shared-engine-bulk PROPERTIES TIMEOUT 45 ENVIRONMENT "PS3RECOMP_ENG_VERTEX_BULK=1")
add_test(NAME shared-engine-bulk-profile COMMAND buzz_rsx_engine_test)
set_tests_properties(shared-engine-bulk-profile PROPERTIES TIMEOUT 45 ENVIRONMENT "PS3RECOMP_ENG_VERTEX_BULK=1;PS3RECOMP_ENG_PROGRAM_PAIR_ONCE=1;PS3RECOMP_RSX_ENGINE_PROFILE=1;PS3RECOMP_ENG_TEXTURE_ROWS=1")
set(PS3RECOMP_RSX_VULKAN ON CACHE BOOL "" FORCE)
set(PS3RECOMP_FETCH_VULKAN_DEPS ON CACHE BOOL "" FORCE)
set(PS3RECOMP_BUILD_TESTS OFF CACHE BOOL "" FORCE)
add_subdirectory("${BUZZ_ROOT}/ps3recomp" sdk EXCLUDE_FROM_ALL)
if(NOT PS3RECOMP_SPIRV_TRANSLATION)
    # The SDK is a subdirectory: the translator's target properties are the
    # authoritative check, rather than a variable in its directory scope.
    get_source_file_property(VK_SHADER_DEFINES "${BUZZ_ROOT}/ps3recomp/libs/video/rsx_shader_spirv.cpp" DIRECTORY "${BUZZ_ROOT}/ps3recomp" COMPILE_DEFINITIONS)
    if(NOT VK_SHADER_DEFINES MATCHES "PS3RECOMP_HAVE_SPIRV_TRANSLATION")
        message(FATAL_ERROR "Vulkan bring-up requires real guest shader translation, not a stub")
    endif()
endif()
add_executable(buzz_vulkan_smoke vulkan-smoke.c "${BUZZ_ROOT}/ps3recomp/runtime/host/host_stubs.c")
target_include_directories(buzz_vulkan_smoke PRIVATE "${BUZZ_ROOT}/ps3recomp/libs/video")
target_link_libraries(buzz_vulkan_smoke PRIVATE ps3recomp_runtime)
set_target_properties(buzz_vulkan_smoke PROPERTIES LINKER_LANGUAGE CXX)
if(WIN32)
    target_link_libraries(buzz_vulkan_smoke PRIVATE user32 gdi32 winmm d3d12 dxgi d3dcompiler)
else()
    target_link_libraries(buzz_vulkan_smoke PRIVATE m)
endif()
add_test(NAME vulkan-headless-clear-and-shaders COMMAND buzz_vulkan_smoke)
add_test(NAME vulkan-headless-dump-roundtrip COMMAND buzz_vulkan_smoke --dump-roundtrip "${CMAKE_CURRENT_BINARY_DIR}/synthetic-clear.ppm")
set_tests_properties(vulkan-headless-clear-and-shaders vulkan-headless-dump-roundtrip PROPERTIES TIMEOUT 45)
add_test(NAME vulkan-frame-dump-forces-readback COMMAND buzz_vulkan_smoke --dump-forces-readback "${CMAKE_CURRENT_BINARY_DIR}/synthetic-forced-readback.ppm")
set_tests_properties(vulkan-frame-dump-forces-readback PROPERTIES TIMEOUT 45)
add_test(NAME vulkan-one-shot-dump COMMAND buzz_vulkan_smoke --dump-once "${CMAKE_CURRENT_BINARY_DIR}/synthetic-once.ppm")
set_tests_properties(vulkan-one-shot-dump PROPERTIES TIMEOUT 45)
foreach(delay 0 -1 3600001 2oops +1 9999999999999999999999999 missing-path)
    add_test(NAME vulkan-one-shot-invalid-${delay} COMMAND buzz_vulkan_smoke --invalid-dump-once "${delay}")
    set_tests_properties(vulkan-one-shot-invalid-${delay} PROPERTIES TIMEOUT 10)
endforeach()
if(WIN32)
    add_test(NAME vulkan-window-readback COMMAND buzz_vulkan_smoke --window)
    add_test(NAME vulkan-window-no-readback COMMAND buzz_vulkan_smoke --window-no-readback)
    set_tests_properties(vulkan-window-readback vulkan-window-no-readback PROPERTIES TIMEOUT 45)
endif()
add_executable(buzz_vulkan_batch_test vulkan-batch-test.c "${BUZZ_ROOT}/ps3recomp/runtime/host/host_stubs.c")
target_include_directories(buzz_vulkan_batch_test PRIVATE "${BUZZ_ROOT}/ps3recomp/libs/video" "${PS3RECOMP_VULKAN_INCLUDE_DIR}")
target_link_libraries(buzz_vulkan_batch_test PRIVATE ps3recomp_runtime)
set_target_properties(buzz_vulkan_batch_test PROPERTIES LINKER_LANGUAGE CXX)
if(WIN32)
    target_link_libraries(buzz_vulkan_batch_test PRIVATE user32 gdi32 winmm d3d12 dxgi d3dcompiler)
else()
    target_link_libraries(buzz_vulkan_batch_test PRIVATE m)
endif()
foreach(size 0 1 3 64)
    add_test(NAME vulkan-draw-batch-${size} COMMAND buzz_vulkan_batch_test ${size})
    set_tests_properties(vulkan-draw-batch-${size} PROPERTIES TIMEOUT 45)
endforeach()
add_test(NAME vulkan-gpu-timestamps-reference COMMAND buzz_vulkan_batch_test 0)
set_tests_properties(vulkan-gpu-timestamps-reference PROPERTIES TIMEOUT 45 SKIP_RETURN_CODE 77 ENVIRONMENT "PS3RECOMP_VK_GPU_TIMESTAMPS=1;PS3RECOMP_VK_PROFILE=1")
add_test(NAME vulkan-gpu-timestamps-batched COMMAND buzz_vulkan_batch_test 512)
set_tests_properties(vulkan-gpu-timestamps-batched PROPERTIES TIMEOUT 45 SKIP_RETURN_CODE 77 ENVIRONMENT "PS3RECOMP_VK_GPU_TIMESTAMPS=1;PS3RECOMP_VK_PROFILE=1;PS3RECOMP_VK_DRAW_RING=1;PS3RECOMP_VK_DRAW_PASSES=1;PS3RECOMP_VK_DRAW_CLEARS=1")
foreach(size 1 3 64 128 512)
    add_test(NAME vulkan-draw-clears-${size} COMMAND buzz_vulkan_batch_test ${size})
    set_tests_properties(vulkan-draw-clears-${size} PROPERTIES TIMEOUT 45 ENVIRONMENT "PS3RECOMP_VK_DRAW_RING=1;PS3RECOMP_VK_DRAW_PASSES=1;PS3RECOMP_VK_DRAW_CLEARS=1")
endforeach()
add_test(NAME vulkan-draw-batch-full-texture-waits COMMAND buzz_vulkan_batch_test 64)
set_tests_properties(vulkan-draw-batch-full-texture-waits PROPERTIES TIMEOUT 45 ENVIRONMENT "PS3RECOMP_VK_CAPTURED_LABELS=0")
foreach(size 0 1 3 64 128 512)
    add_test(NAME vulkan-draw-ring-${size} COMMAND buzz_vulkan_batch_test ${size})
    set_tests_properties(vulkan-draw-ring-${size} PROPERTIES TIMEOUT 45 ENVIRONMENT "PS3RECOMP_VK_DRAW_RING=1")
endforeach()
add_test(NAME vulkan-draw-ring-full-texture-waits COMMAND buzz_vulkan_batch_test 64)
set_tests_properties(vulkan-draw-ring-full-texture-waits PROPERTIES TIMEOUT 45 ENVIRONMENT "PS3RECOMP_VK_DRAW_RING=1;PS3RECOMP_VK_CAPTURED_LABELS=0")
foreach(size 1 3 64 128 512)
    add_test(NAME vulkan-draw-passes-${size} COMMAND buzz_vulkan_batch_test ${size})
    set_tests_properties(vulkan-draw-passes-${size} PROPERTIES TIMEOUT 45 ENVIRONMENT "PS3RECOMP_VK_DRAW_RING=1;PS3RECOMP_VK_DRAW_PASSES=1")
endforeach()
