option(ENABLE_NX "Build mesa for offline NX shader compilation and runtime" OFF) find_program(MESON_PROG meson) find_program(NINJA_PROG ninja) if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/mesa/meson.build AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/libdrm_nouveau/Makefile AND MESON_PROG AND NINJA_PROG AND ENABLE_NX) message(STATUS "Enabling NX support") set(LIBDRM_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libdrm_nouveau) set(MESA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/mesa) set(MESA_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/mesa) file(MAKE_DIRECTORY ${MESA_BUILD_DIR}) if(NOT NX) set(PLAT_MESA_TARGETS src/mesa/libmesa_sse41.a) else() set(PLAT_MESA_TARGETS src/gallium/winsys/nouveau/switch/libnouveauwinsys.a) endif() set(MESA_TARGETS src/compiler/libcompiler.a src/compiler/glsl/libglsl.a src/compiler/glsl/glcpp/libglcpp.a src/compiler/nir/libnir.a src/libglsl_util.a src/util/libmesa_util.a src/mesa/libmesa_gallium.a ${PLAT_MESA_TARGETS} src/gallium/auxiliary/libgallium.a src/gallium/auxiliary/libgalliumvl.a src/gallium/drivers/nouveau/libnouveau.a) include_directories( ${MESA_DIR}/include ${MESA_DIR}/src ${MESA_DIR}/src/mesa ${MESA_DIR}/src/mapi ${MESA_DIR}/src/compiler/glsl ${MESA_BUILD_DIR}/src/compiler ${MESA_DIR}/src/mesa/state_tracker ${MESA_DIR}/src/gallium/include ${MESA_DIR}/src/gallium/auxiliary ${MESA_DIR}/src/gallium/drivers/nouveau ${LIBDRM_DIR}/include) if(${CMAKE_BUILD_TYPE} STREQUAL Release OR ${CMAKE_BUILD_TYPE} STREQUAL RelWithDebInfo) set(MESON_BUILD_TYPE release) set(MESON_SANITIZE_ARGS "") else() set(MESON_BUILD_TYPE debug) set(MESON_SANITIZE_ARGS "-fsanitize=address") endif() if(NX) configure_file(switch_cross_file.txt.in switch_cross_file.txt) set(MESON_CROSS --cross-file ${CMAKE_CURRENT_BINARY_DIR}/switch_cross_file.txt -D c_std=gnu11 -D cpp_std=gnu++17) set(MESA_PLATFORMS switch) endif() if(NOT EXISTS ${MESA_BUILD_DIR}/build.ninja) message(STATUS "Preparing mesa build system") set(ENV{CC} "") set(ENV{CXX} "") execute_process(COMMAND ${MESON_PROG} setup -D buildtype=${MESON_BUILD_TYPE} ${MESON_CROSS} -D gallium-drivers=nouveau -D dri-drivers= -D vulkan-drivers= -D llvm=false -D shared-glapi=true -D gles1=false -D gles2=false -D gbm=false -D shader-cache=false -D boo-offline-mode=true -D "platforms=${MESA_PLATFORMS}" -D glx=disabled -D "c_args=${MESON_SANITIZE_ARGS} -I${LIBDRM_DIR}/include -DDEBUG=1 -DHAVE_LIBDRM" -D "cpp_args=${MESON_SANITIZE_ARGS} -I${LIBDRM_DIR}/include -DDEBUG=1 -DHAVE_LIBDRM" -D "c_link_args=${MESON_SANITIZE_ARGS}" -D "cpp_link_args=${MESON_SANITIZE_ARGS}" ${MESA_DIR} ${MESA_BUILD_DIR} RESULT_VARIABLE MESON_RESULT) if(NOT MESON_RESULT EQUAL 0) message(FATAL_ERROR "meson failed with error code ${MESON_RESULT}") endif() endif() message(STATUS "Invoking mesa build system") execute_process(COMMAND ${NINJA_PROG} -C ${MESA_BUILD_DIR} ${MESA_TARGETS} RESULT_VARIABLE NINJA_RESULT) if(NOT NINJA_RESULT EQUAL 0) message(FATAL_ERROR "ninja failed with error code ${NINJA_RESULT}") endif() if(NOT WIN32) add_definitions("-DHAVE_PTHREAD -DHAVE_TIMESPEC_GET") if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) add_definitions("-DHAVE_LINUX_FUTEX_H") endif() endif() add_definitions("-DHAVE_ZLIB -DDEBUG=1 -DHAVE_LIBDRM") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=return-type") add_subdirectory(fake_libdrm_nouveau) add_library(nx_compiler nx_compiler.cpp ${MESA_DIR}/src/compiler/glsl/ir_builder_print_visitor.cpp) target_link_libraries(nx_compiler ${MESA_BUILD_DIR}/src/mesa/libmesa_gallium.a ${MESA_BUILD_DIR}/src/mesa/libmesa_sse41.a ${MESA_BUILD_DIR}/src/compiler/nir/libnir.a ${MESA_BUILD_DIR}/src/compiler/glsl/libglsl.a ${MESA_BUILD_DIR}/src/libglsl_util.a ${MESA_BUILD_DIR}/src/compiler/glsl/glcpp/libglcpp.a ${MESA_BUILD_DIR}/src/compiler/libcompiler.a ${MESA_BUILD_DIR}/src/gallium/drivers/nouveau/libnouveau.a ${MESA_BUILD_DIR}/src/gallium/auxiliary/libgallium.a ${MESA_BUILD_DIR}/src/gallium/auxiliary/libgalliumvl.a ${MESA_BUILD_DIR}/src/util/libmesa_util.a fake_libdrm_nouveau unwind dl pthread z) add_executable(nx_compiler_driver nx_compiler_driver.cpp) target_link_libraries(nx_compiler_driver nx_compiler) if(COMMAND add_sanitizers) add_sanitizers(nx_compiler nx_compiler_driver) endif() if(NX) include_directories(${DEVKITPRO}/libnx/include) add_library(libdrm_nouveau libdrm_nouveau/source/bomap.c libdrm_nouveau/source/bufctx.c libdrm_nouveau/source/nouveau.c libdrm_nouveau/source/pushbuf.c) add_definitions(-DBOO_HAS_NX=1) add_library(nx_runtime NX.cpp nx_compiler.cpp ${MESA_DIR}/src/compiler/glsl/ir_builder_print_visitor.cpp) target_link_libraries(nx_runtime xxhash ${MESA_BUILD_DIR}/src/mesa/libmesa_gallium.a ${MESA_BUILD_DIR}/src/compiler/nir/libnir.a ${MESA_BUILD_DIR}/src/compiler/glsl/libglsl.a ${MESA_BUILD_DIR}/src/libglsl_util.a ${MESA_BUILD_DIR}/src/compiler/glsl/glcpp/libglcpp.a ${MESA_BUILD_DIR}/src/compiler/libcompiler.a ${MESA_BUILD_DIR}/src/gallium/drivers/nouveau/libnouveau.a ${MESA_BUILD_DIR}/src/gallium/winsys/nouveau/switch/libnouveauwinsys.a ${MESA_BUILD_DIR}/src/gallium/auxiliary/libgallium.a ${MESA_BUILD_DIR}/src/gallium/auxiliary/libgalliumvl.a ${MESA_BUILD_DIR}/src/util/libmesa_util.a libdrm_nouveau nx) if(COMMAND add_sanitizers) add_sanitizers(nx_runtime libdrm_nouveau) endif() endif() else() if(NX) message(FATAL_ERROR "Unable to find meson or ninja or mesa submodules; this is required for NX.") elseif(ENABLE_NX) message(STATUS "Unable to find meson or ninja or mesa submodules; skipping NX support.") endif() endif()