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
117 changes: 109 additions & 8 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@ name: Build and Release

on:
push:
branches: [ master, main ]
branches:
- master
- main
- 'releases/**'
tags:
- 'v*'
- '*'
pull_request:
branches: [ master, main ]
branches:
- master
- main
workflow_dispatch:

jobs:
build-windows:
name: Build Windows
runs-on: windows-latest
env:
VULKAN_SDK: C:\VulkanSDK\1.3.290.0
Expand Down Expand Up @@ -71,21 +78,115 @@ jobs:
name: windows-bin
path: RacingEngine-Windows.zip

build-linux:
name: Build Linux
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install -y libvulkan-dev libglfw3-dev libglm-dev build-essential cmake libxkbcommon-dev libxcursor-dev libxi-dev libxinerama-dev vulkan-tools glslang-tools

- name: Clone dependencies
run: |
mkdir -p external
git clone --depth 1 https://github.com/glfw/glfw.git external/glfw
git clone --depth 1 https://github.com/g-truc/glm.git external/glm

- name: Compile Shaders
run: |
mkdir -p shaders/compiled
glslangValidator -V shaders/raygen.rgen -o shaders/compiled/raygen.rgen.spv --target-env vulkan1.3
glslangValidator -V shaders/miss.rmiss -o shaders/compiled/miss.rmiss.spv --target-env vulkan1.3
glslangValidator -V shaders/closesthit.rchit -o shaders/compiled/closesthit.rchit.spv --target-env vulkan1.3
glslangValidator -V shaders/shadow.rmiss -o shaders/compiled/shadow.rmiss.spv --target-env vulkan1.3
glslangValidator -V shaders/tonemap.comp -o shaders/compiled/tonemap.comp.spv --target-env vulkan1.3

- name: Configure CMake
run: cmake -B build -S . -DCMAKE_BUILD_TYPE=Release

- name: Build
run: cmake --build build

- name: Package
run: |
mkdir release
cp build/RacingEngine release/
mkdir -p release/shaders/compiled
cp shaders/compiled/*.spv release/shaders/compiled/
if [ -d "assets" ]; then
cp -r assets release/
fi
tar -czvf RacingEngine-Linux.tar.gz -C release .

- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: linux-bin
path: RacingEngine-Linux.tar.gz

build-android:
name: Build Android
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up NDK
run: echo "Using pre-installed NDK at $ANDROID_NDK_LATEST_HOME"

- name: Clone dependencies
run: |
mkdir -p external
git clone --depth 1 https://github.com/g-truc/glm.git external/glm

- name: Configure and Build
run: |
cmake -B build-android -S . \
-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_LATEST_HOME/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=arm64-v8a \
-DANDROID_PLATFORM=android-29 \
-DANDROID_NATIVE_API_LEVEL=29 \
-DCMAKE_BUILD_TYPE=Release
cmake --build build-android

- name: Package
run: cp build-android/libRacingEngine.so .

- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: android-bin
path: libRacingEngine.so

release:
needs: [build-windows]
if: startsWith(github.ref, 'refs/tags/')
name: Create Release
needs: [build-windows, build-linux, build-android]
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts

- name: List artifacts
run: ls -R
run: ls -R artifacts

- name: Create Release
- name: Publish Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_type == 'tag' && github.ref_name || 'latest' }}
files: |
windows-bin/RacingEngine-Windows.zip
artifacts/windows-bin/RacingEngine-Windows.zip
artifacts/linux-bin/RacingEngine-Linux.tar.gz
artifacts/android-bin/libRacingEngine.so
generate_release_notes: true
prerelease: ${{ github.ref_type != 'tag' }}
fail_on_unmatched_files: false
41 changes: 25 additions & 16 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,17 @@ else()
endif()

# GLFW
# Check if external/glfw exists, otherwise try system package
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/external/glfw/CMakeLists.txt")
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(GLFW_USE_MSVC_RUNTIME_LIBRARY_DLL ON CACHE BOOL "" FORCE)
add_subdirectory(external/glfw)
else()
find_package(glfw3 REQUIRED)
if(NOT ANDROID)
# Check if external/glfw exists, otherwise try system package
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/external/glfw/CMakeLists.txt")
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(GLFW_USE_MSVC_RUNTIME_LIBRARY_DLL ON CACHE BOOL "" FORCE)
add_subdirectory(external/glfw)
else()
find_package(glfw3 REQUIRED)
endif()
endif()

# Add GLM (header-only)
Expand All @@ -97,15 +99,22 @@ endif()
file(GLOB_RECURSE CPP_SOURCES "src/*.cpp")
file(GLOB_RECURSE HEADERS "src/*.h")

# Create executable
add_executable(${PROJECT_NAME}
${CPP_SOURCES}
${HEADERS}
)
# Create target
if(ANDROID)
add_library(${PROJECT_NAME} SHARED
${CPP_SOURCES}
${HEADERS}
)
else()
add_executable(${PROJECT_NAME}
${CPP_SOURCES}
${HEADERS}
)
endif()

# Link libraries
if(TARGET glfw)
target_link_libraries(${PROJECT_NAME} Vulkan::Vulkan glfw)
if(ANDROID)
target_link_libraries(${PROJECT_NAME} Vulkan::Vulkan android log)
else()
target_link_libraries(${PROJECT_NAME} Vulkan::Vulkan glfw)
endif()
Expand Down
2 changes: 2 additions & 0 deletions src/Camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ void Camera::update(float deltaTime) {
// For now, all updates happen in processKeyboard
}

#ifndef ANDROID
void Camera::processKeyboard(GLFWwindow* window, float deltaTime) {
float velocity = movementSpeed * deltaTime;

Expand All @@ -75,6 +76,7 @@ void Camera::processKeyboard(GLFWwindow* window, float deltaTime) {
else
movementSpeed = 5.0f;
}
#endif

void Camera::processMouseMovement(float xOffset, float yOffset) {
xOffset *= mouseSensitivity;
Expand Down
4 changes: 4 additions & 0 deletions src/Camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#ifndef ANDROID
#include <GLFW/glfw3.h>
#endif

class Camera {
public:
Expand All @@ -21,7 +23,9 @@ class Camera {
void reset();

// Input handling
#ifndef ANDROID
void processKeyboard(GLFWwindow* window, float deltaTime);
#endif
void processMouseMovement(float xOffset, float yOffset);
void processMouseScroll(float yOffset);

Expand Down
19 changes: 17 additions & 2 deletions src/VulkanRTPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@
#include <fstream>
#include <cstring>

void VulkanRTPipeline::loadRTPipelineFunctions(VkDevice device) {
void VulkanRTPipeline::loadRTPipelineFunctions(VkInstance instance, VkDevice device) {
vkGetRayTracingShaderGroupHandlesKHR = (PFN_vkGetRayTracingShaderGroupHandlesKHR)
vkGetDeviceProcAddr(device, "vkGetRayTracingShaderGroupHandlesKHR");
vkCreateRayTracingPipelinesKHR = (PFN_vkCreateRayTracingPipelinesKHR)
vkGetDeviceProcAddr(device, "vkCreateRayTracingPipelinesKHR");
vkCmdTraceRaysKHR = (PFN_vkCmdTraceRaysKHR)
vkGetDeviceProcAddr(device, "vkCmdTraceRaysKHR");

vkGetPhysicalDeviceProperties2KHR = (PFN_vkGetPhysicalDeviceProperties2KHR)
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2KHR");
if (!vkGetPhysicalDeviceProperties2KHR) {
vkGetPhysicalDeviceProperties2KHR = (PFN_vkGetPhysicalDeviceProperties2KHR)
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2");
}

std::cout << "RT pipeline function pointers loaded\n";
}

Expand Down Expand Up @@ -374,7 +381,15 @@ void VulkanRTPipeline::createShaderBindingTable(VkPhysicalDevice physicalDevice,
VkPhysicalDeviceProperties2 deviceProps{};
deviceProps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
deviceProps.pNext = &rtProperties;
vkGetPhysicalDeviceProperties2(physicalDevice, &deviceProps);

if (vkGetPhysicalDeviceProperties2KHR) {
vkGetPhysicalDeviceProperties2KHR(physicalDevice, &deviceProps);
} else {
std::cerr << "Warning: vkGetPhysicalDeviceProperties2 not available, RT properties may be invalid\n";
// Fallback to basic properties, though rtProperties will remain uninitialized by the call
VkPhysicalDeviceProperties basicProps;
vkGetPhysicalDeviceProperties(physicalDevice, &basicProps);
}

handleSize = rtProperties.shaderGroupHandleSize;

Expand Down
3 changes: 2 additions & 1 deletion src/VulkanRTPipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ class VulkanRTPipeline {
PFN_vkGetRayTracingShaderGroupHandlesKHR vkGetRayTracingShaderGroupHandlesKHR;
PFN_vkCreateRayTracingPipelinesKHR vkCreateRayTracingPipelinesKHR;
PFN_vkCmdTraceRaysKHR vkCmdTraceRaysKHR;
PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR;

void loadRTPipelineFunctions(VkDevice device);
void loadRTPipelineFunctions(VkInstance instance, VkDevice device);
void createDescriptorSetLayout(VkDevice device);
void createDescriptorPool(VkDevice device);
void createDescriptorSet(VkDevice device, VkAccelerationStructureKHR tlas,
Expand Down
4 changes: 4 additions & 0 deletions src/VulkanRayTracing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,11 @@ void VulkanRayTracing::createAccumulationImage(VkPhysicalDevice physicalDevice,
// Prepare for external memory export (for CUDA interop)
VkExportMemoryAllocateInfo exportAllocInfo{};
exportAllocInfo.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO;
#ifdef _WIN32
exportAllocInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;
#else
exportAllocInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
#endif

VkMemoryAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
Expand Down
Loading