Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
build/*
# any build subdirectory in the tree
**/build/
**/build_web/
examples/hello_gpu/build/*
examples/raymarch/build/*
docs/html
source
.DS_Store
third_party/lib/*
third_party/local/*
third_party/dawn/*

# formatter files
.cmake-format.py
Expand All @@ -20,3 +22,6 @@ build
.cache
compile_commands.json

# editor specific
.vscode/*

30 changes: 4 additions & 26 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,23 +1,13 @@
# This only builds a shared lib, see cmake/example.cmake
# and cmake/gpu.cmake for more details
cmake_minimum_required(VERSION 3.28)
project(gpu)

include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/webgpu.cmake")

set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # export compile_commands.json to use with
# LSP
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

option(USE_LOCAL_LIBS
"Use local libraries instead of fetching from the internet" OFF)

# Ensure the build type is set
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE
Release
CACHE STRING "Choose the type of build: Debug or Release" FORCE)
endif()

option(FASTBUILD "Option to enable fast builds" OFF)
if(FASTBUILD)
set(CMAKE_BUILD_TYPE None) # Avoid default flags of predefined build types
Expand All @@ -30,21 +20,9 @@ if(DEBUG)
set(CMAKE_CXX_FLAGS "-O0 -g")
endif()

if(WIN64)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWEBGPU_BACKEND_DAWN")
endif()

include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/dawn.cmake")
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/gpu.cmake")

message(STATUS "CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}")
message(
STATUS
"Include directories for wgpu: ${CMAKE_CURRENT_SOURCE_DIR}/third_party/headers"
)

add_library(gpud SHARED gpu.hpp)
set_target_properties(gpud PROPERTIES LINKER_LANGUAGE CXX)
target_link_libraries(gpud PRIVATE wgpu)
target_link_libraries(gpud PRIVATE webgpu)
target_link_libraries(gpud PRIVATE gpu)
install(TARGETS gpud)
122 changes: 122 additions & 0 deletions cmake/dawn.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# Setup directories
set(FETCHCONTENT_BASE_DIR "${PROJECT_ROOT}/third_party")
set(DAWN_DIR "${FETCHCONTENT_BASE_DIR}/dawn" CACHE INTERNAL "")
set(DAWN_BUILD_DIR "${DAWN_DIR}/build" CACHE INTERNAL "")

if(EMSCRIPTEN)
set(EM_SDK_DIR $ENV{EMSDK} CACHE INTERNAL "")
set(DAWN_BUILD_DIR "${DAWN_DIR}/build_web" CACHE INTERNAL "")
set(DAWN_EMSCRIPTEN_TOOLCHAIN ${EM_SDK_DIR}/upstream/emscripten CACHE INTERNAL "" FORCE)
endif()

# Enable find for no dawn rebuilds with flutter run
set(ENABLE_DAWN_FIND OFF CACHE BOOL "Enable finding Dawn" FORCE)
set(DAWN_BUILD_FOUND OFF CACHE BOOL "Dawn build found" FORCE)
if(ENABLE_DAWN_FIND)
# find_library, windows adds extra folder
if(MSVC)
find_library(WEBGPU_DAWN_DEBUG webgpu_dawn
NAMES webgpu_dawn
HINTS "${DAWN_BUILD_DIR}/src/dawn/native/Debug"
)
find_library(WEBGPU_DAWN_RELEASE webgpu_dawn
NAMES webgpu_dawn
HINTS "${DAWN_BUILD_DIR}/src/dawn/native/Release"
)
set(DAWN_BUILD_FOUND ON)
elseif(NOT EMSCRIPTEN AND NOT MSVC)
find_library(WEBGPU_DAWN_LIB
NAMES webgpu_dawn
PATHS "${DAWN_BUILD_DIR}/src/dawn/native"
REQUIRED
)
set(DAWN_BUILD_FOUND ON)
else()
set(DAWN_BUILD_FOUND ON)
endif()
endif()

# Dawn options for more,
# see https://dawn.googlesource.com/dawn/+/refs/heads/main/CMakeLists.txt
set(DAWN_ALWAYS_ASSERT OFF CACHE INTERNAL "Always assert in Dawn" FORCE)
set(DAWN_BUILD_MONOLITHIC_LIBRARY ON CACHE INTERNAL "Build Dawn monolithically" FORCE)
set(DAWN_BUILD_EXAMPLES OFF CACHE INTERNAL "Build Dawn examples" FORCE)
set(DAWN_BUILD_SAMPLES OFF CACHE INTERNAL "Build Dawn samples" FORCE)
set(DAWN_BUILD_TESTS OFF CACHE INTERNAL "Build Dawn tests" FORCE)
set(DAWN_ENABLE_INSTALL OFF CACHE INTERNAL "Enable Dawn installation" FORCE)
set(DAWN_FETCH_DEPENDENCIES ON CACHE INTERNAL "Fetch Dawn dependencies" FORCE)
set(TINT_BUILD_TESTS OFF CACHE INTERNAL "Build Tint Tests" FORCE)
set(TINT_BUILD_IR_BINARY OFF CACHE INTERNAL "Build Tint IR binary" FORCE)
set(TINT_BUILD_CMD_TOOLS OFF CACHE INTERNAL "Build Tint command line tools" FORCE)

if(NOT DAWN_BUILD_FOUND)
include(FetchContent)
message("webgpu_dawn not found start building")
if(EMSCRIPTEN)
set(EMSCRIPTEN_DIR "${EM_SDK_DIR}/upstream/emscripten" CACHE INTERNAL "" FORCE)
set(DAWN_EMSCRIPTEN_TOOLCHAIN ${EMSCRIPTEN_DIR} CACHE INTERNAL "" FORCE)
endif()

FetchContent_Declare(
dawn
DOWNLOAD_DIR ${DAWN_DIR}
SOURCE_DIR ${DAWN_DIR}
SUBBUILD_DIR ${DAWN_BUILD_DIR}/tmp
BINARY_DIR ${DAWN_BUILD_DIR}
DOWNLOAD_COMMAND
cd ${DAWN_DIR} &&
git init &&
git fetch --depth=1 https://dawn.googlesource.com/dawn &&
git reset --hard FETCH_HEAD
)

# Download the repository and add it as a subdirectory.
FetchContent_MakeAvailable(dawn)

# attempt fix flutter rebuilds
set(CMAKE_INCLUDE_PATH "${CMAKE_INCLUDE_PATH};${DAWN_DIR}/src" CACHE INTERNAL "")

execute_process(
WORKING_DIRECTORY ${DAWN_DIR}
COMMAND ${CMAKE_COMMAND} -S ${DAWN_DIR}
-B ${DAWN_BUILD_DIR}
)

# Build Dawn
execute_process(
COMMAND ${CMAKE_COMMAND} --build ${DAWN_BUILD_DIR}
)

# find_library, windows adds extra folder
if(MSVC)
find_library(WEBGPU_DAWN_DEBUG webgpu_dawn
NAMES webgpu_dawn
HINTS "${DAWN_BUILD_DIR}/src/dawn/native/Debug"
)
find_library(WEBGPU_DAWN_RELEASE webgpu_dawn
NAMES webgpu_dawn
HINTS "${DAWN_BUILD_DIR}/src/dawn/native/Release"
)
set(DAWN_BUILD_FOUND ON)
elseif(NOT EMSCRIPTEN AND NOT MSVC)
find_library(WEBGPU_DAWN_LIB
NAMES webgpu_dawn
PATHS "${DAWN_BUILD_DIR}/src/dawn/native"
REQUIRED
)
set(DAWN_BUILD_FOUND ON)
else()
set(DAWN_BUILD_FOUND ON)
endif()
endif()

if(EMSCRIPTEN)
add_library(webgpu_dawn INTERFACE IMPORTED)
target_include_directories(webgpu_dawn INTERFACE ${DAWN_BUILD_DIR}/gen/src/emdawnwebgpu/include)
target_include_directories(webgpu_dawn INTERFACE ${DAWN_BUILD_DIR}/gen/src/emdawnwebgpu/include/webgpu/webgpu.h)
target_link_libraries(webgpu_dawn INTERFACE ${DAWN_BUILD_DIR}/gen/src/emdawnwebgpu/library_webgpu_enum_tables.js)
target_link_libraries(webgpu_dawn INTERFACE ${DAWN_BUILD_DIR}/gen/src/emdawnwebgpu/library_webgpu_generated_struct_info.js)
target_link_libraries(webgpu_dawn INTERFACE ${DAWN_BUILD_DIR}/gen/src/emdawnwebgpu/library_webgpu_generated_sig_info.js)
target_link_libraries(webgpu_dawn INTERFACE ${DAWN_DIR}/third_party/emdawnwebgpu/library_webgpu.js)
else()
endif()
133 changes: 81 additions & 52 deletions cmake/example.cmake
Original file line number Diff line number Diff line change
@@ -1,68 +1,97 @@
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # export compile_commands.json to use with
# LSP
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Getting Started with CMAKE
# Each example includes this and sets PROJECT_NAME.
#
# Example usage:
# cd examples/hello_world
# cmake -S . build/ -DCMAKE_BUILD_TYPE=Release
# cmake --build build/ --config Release
# ./build/hello_world (or serve the output .js/.wasm for Emscripten)
# or for emscripten
# emcmake cmake -S . -B ./build_web -DCMAKE_BUILD_TYPE=Release
# cmake --build build_web --config Release
# python3 -m http.server 8080 --d build_web

if(NOT MSVC)
set(CMAKE_CXX_STANDARD 17)
else()
set(CMAKE_CXX_STANDARD 20)
endif()

# Locate the project root (two levels up from the current source dir)
get_filename_component(PROJECT_ROOT ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
get_filename_component(PROJECT_ROOT ${PROJECT_ROOT} DIRECTORY)

# Construct potential paths
set(FILEPATH_CURRENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}")
set(FILEPATH_PROJECT_ROOT "${PROJECT_ROOT}/${FILENAME}")
# Include external libraries and helper scripts (dawn and gpu)
include("${PROJECT_ROOT}/cmake/dawn.cmake")
include("${PROJECT_ROOT}/cmake/gpu.cmake")

# Include file finding utility script
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/find_gpu.cmake")
# Create the executable
add_executable(${PROJECT_NAME} run.cpp)

# Check if the file exists in the current directory
find_project_root(${CMAKE_CURRENT_SOURCE_DIR} ${FILENAME}
TARGET_FILE_PATH)
if("${TARGET_FILE_PATH}" STREQUAL "")
find_project_root(${FILEPATH_CURRENT_DIR} ${FILENAME}
TARGET_FILE_PATH)
if("${TARGET_FILE_PATH}" STREQUAL "")
message(
FATAL_ERROR
"File ${FILENAME} not found in either ${CMAKE_CURRENT_SOURCE_DIR} or ${CMAKE_CURRENT_SOURCE_DIR}/../../"
)
endif()
endif()
# Platform-specific linking & build settings
if(EMSCRIPTEN)
# Emscripten-specific configuration

# Ensure the build type is set
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE
Release
CACHE STRING "Choose the type of build: Debug or Release" FORCE)
endif()
# Define a web output directory (adjust as needed)
set(WEB_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/web_build")

# Define architecture and build type directories or file names
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(ARCH "x64")
else()
set(ARCH "x86")
endif()
# If necessary, include the generated WebGPU include dirs first.
include_directories(BEFORE "${DAWN_BUILD_DIR}/gen/src/emdawnwebgpu/include/")

if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(BUILD_TYPE "Debug")
else()
set(BUILD_TYPE "Release")
endif()
# Create a helper library for WebGPU support.
add_library(webgpu_web "${DAWN_DIR}/third_party/emdawnwebgpu/webgpu.cpp")
target_link_libraries(${PROJECT_NAME} PRIVATE webgpu_web)

# Set Emscripten-specific link flags that enable WASM output and expose certain symbols.
# Needed to use updated version, emdawnwebgpu
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "\
-sUSE_WEBGPU=0 \
-sWASM=1 \
-DDAWN_EMSCRIPTEN_TOOLCHAIN=${EMSCRIPTEN_DIR} \
-sEXPORTED_FUNCTIONS=_main,_malloc,_free,_memcpy \
-sEXPORTED_RUNTIME_METHODS=ccall \
-sUSE_GLFW=3 \
-sALLOW_MEMORY_GROWTH=1 -sSTACK_SIZE=5MB \
-sASYNCIFY \
--js-library=${DAWN_BUILD_DIR}/gen/src/emdawnwebgpu/library_webgpu_enum_tables.js \
--js-library=${DAWN_BUILD_DIR}/gen/src/emdawnwebgpu/library_webgpu_generated_struct_info.js \
--js-library=${DAWN_BUILD_DIR}/gen/src/emdawnwebgpu/library_webgpu_generated_sig_info.js \
--js-library=${DAWN_DIR}/third_party/emdawnwebgpu/library_webgpu.js \
--closure-args=--externs=${EMSCRIPTEN_DIR}/src/closure-externs/webgpu-externs.js \
")

if(NOT TARGET gpu)
message(STATUS "GPU_LIB not found")
include("${TARGET_FILE_PATH}/cmake/webgpu.cmake")
include("${TARGET_FILE_PATH}/cmake/gpu.cmake")
else()
# Non-Emscripten (desktop) linking
if(MSVC)
target_link_libraries(gpu
PRIVATE
$<$<CONFIG:Debug>:${WEBGPU_DAWN_DEBUG}>
$<$<CONFIG:Release>:${WEBGPU_DAWN_RELEASE}>
)
else()
target_link_libraries(gpu PRIVATE webgpu_dawn)
endif()
endif()

add_executable(${PROJECT_NAME} run.cpp)
# Link the gpu/dawn library to the executable.
target_link_libraries(${PROJECT_NAME} PRIVATE gpu)
target_link_libraries(${PROJECT_NAME} PRIVATE wgpu)
target_link_libraries(${PROJECT_NAME} PRIVATE webgpu)

if(WIN32)
# Ensure DLL is copied if on Windows
# Platform-specific post-build actions (e.g. copying DLLs for MSVC)
if(MSVC)
add_custom_command(
TARGET ${PROJECT_NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DLL_PATH}
$<TARGET_FILE_DIR:${PROJECT_NAME}>)
TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${DAWN_BUILD_DIR}/$<CONFIG>/webgpu_dawn.dll
$<TARGET_FILE_DIR:${PROJECT_NAME}>
COMMENT "Copying webgpu_dawn.dll to the build directory"
)
endif()

if(EMSCRIPTEN)

# Configure the HTML file by replacing @PROJECT_NAME@ with the actual target name.
configure_file(${PROJECT_ROOT}cmake/templates/index.html.in
${CMAKE_CURRENT_BINARY_DIR}/index.html
@ONLY)

endif()
30 changes: 0 additions & 30 deletions cmake/find_gpu.cmake

This file was deleted.

Loading