diff --git a/.vscode/settings.json b/.vscode/settings.json index 86c9ad4..b19ea0a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -117,7 +117,12 @@ "string_view": "cpp", "rope": "cpp", "slist": "cpp", - "numbers": "cpp" + "numbers": "cpp", + "barrier": "cpp", + "latch": "cpp", + "ranges": "cpp", + "source_location": "cpp", + "syncstream": "cpp" }, "cmake.skipConfigureIfCachePresent": false, "cmake.configureArgs": [ diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f64b03..188241c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,10 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin/${CMAKE_BUILD set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/bin/Debug) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/bin/Release) +set(Boost_USE_STATIC_LIBS OFF) +if(WIN32) + set(Boost_LIB_PREFIX lib) +endif() find_package(Vulkan REQUIRED) find_package(Boost REQUIRED COMPONENTS serialization) @@ -117,9 +121,11 @@ if(WIN32) add_custom_target(copy-binaries ALL COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SLANG_BINARIES} $ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SLANG_GLSLANG} $ - #COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GLFW_BINARY} $ - #COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ASSIMP_BINARY} $ - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${NSAM_BINARIES} $) + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GLFW_BINARY} $ + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ASSIMP_BINARY} $ + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${NSAM_BINARIES} $ + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${NSAM_LLVM} $ + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${KTX_BINARIES} $) else() add_custom_target(copy-binaries ALL COMMAND "") endif() diff --git a/cmake/FindAftermath.cmake b/cmake/FindAftermath.cmake index a28d6cc..5286209 100644 --- a/cmake/FindAftermath.cmake +++ b/cmake/FindAftermath.cmake @@ -92,7 +92,7 @@ find_package_handle_standard_args(NSAM DEFAULT_MSG NSAM_INCLUDE_DIR NSAM_LIBRARY if (NSAM_FOUND) set(NSAM_LIBRARIES ${NSAM_LIBRARY}) set(NSAM_INCLUDE_DIRS ${NSAM_INCLUDE_DIR}) - set(NSAM_BINARIES ${NSAM_BINARY} ${NSAM_LLVM}) + set(NSAM_BINARIES ${NSAM_BINARY}) endif() # Hide some variables diff --git a/cmake/FindAssimp.cmake b/cmake/FindAssimp.cmake index c0d2180..f8b8622 100644 --- a/cmake/FindAssimp.cmake +++ b/cmake/FindAssimp.cmake @@ -38,7 +38,8 @@ if (WIN32) NAMES assimp-vc${MSVC_TOOLSET_VERSION}-mt${CMAKE_DEBUG_POSTFIX}.dll PATHS $ENV{PROGRAMFILES}/bin - ${ASSIMP_ROOT}/bin) + ${ASSIMP_ROOT}/code + PATH_SUFFIXES Debug Release) else() # Find include files find_path( diff --git a/cmake/FindGLFW.cmake b/cmake/FindGLFW.cmake index 034d747..7119aad 100644 --- a/cmake/FindGLFW.cmake +++ b/cmake/FindGLFW.cmake @@ -48,15 +48,15 @@ if (WIN32) unset(GLFW_LIBRARY_NAME) - #find_file( - # GLFW_BINARY - # NAMES glfw3${CMAKE_DEBUG_POSTFIX}.dll - # PATHS - # $ENV{PROGRAMFILES}/bin - # ${CMAKE_BINARY_DIR} - # ${GLFW_ROOT}/src - # ${GLFW_ROOT}/bin - # PATH_SUFFIXES Debug Release) + find_file( + GLFW_BINARY + NAMES glfw3${CMAKE_DEBUG_POSTFIX}.dll + PATHS + $ENV{PROGRAMFILES}/bin + ${CMAKE_BINARY_DIR} + ${GLFW_ROOT}/src + ${GLFW_ROOT}/bin + PATH_SUFFIXES Debug Release) else() # Find include files find_path( diff --git a/cmake/FindKTX.cmake b/cmake/FindKTX.cmake index 9bc9d4b..fc96699 100644 --- a/cmake/FindKTX.cmake +++ b/cmake/FindKTX.cmake @@ -17,47 +17,56 @@ include(FindPackageHandleStandardArgs) if (WIN32) - # Find include files - find_path( - KTX_INCLUDE_DIR - NAMES ktx.h - PATHS - $ENV{PROGRAMFILES}/include - ${KTX_ROOT}/include - DOC "The directory where ktx.h resides") + # Find include files + find_path( + KTX_INCLUDE_DIR + NAMES ktx.h + PATHS + $ENV{PROGRAMFILES}/include + ${KTX_ROOT}/include + DOC "The directory where ktx.h resides") - # Find library files - find_library( - KTX_LIBRARY - NAMES ktx${CMAKE_DEBUG_POSTFIX}.lib - PATHS - $ENV{PROGRAMFILES}/lib - ${KTX_ROOT} - ${KTX_ROOT}/lib - PATH_SUFFIXES Debug Release) + # Find library files + find_library( + KTX_LIBRARY + NAMES ktx${CMAKE_DEBUG_POSTFIX}.lib + PATHS + $ENV{PROGRAMFILES}/lib + ${KTX_ROOT} + ${KTX_ROOT}/lib + PATH_SUFFIXES Debug Release) + + find_file( + KTX_BINARY + NAMES ktx${CMAKE_DEBUG_POSTFIX}.dll + PATHS + $ENV{PROGRAMFILES}/lib + ${KTX_ROOT} + ${KTX_ROOT}/lib + PATH_SUFFIXES Debug Release) else() - # Find include files - find_path( - KTX_INCLUDE_DIR - NAMES ktx.h - PATHS - /usr/include - /usr/local/include - /sw/include - /opt/local/include - ${KTX_ROOT} - DOC "The directory where KTX/ktx.h resides") + # Find include files + find_path( + KTX_INCLUDE_DIR + NAMES ktx.h + PATHS + /usr/include + /usr/local/include + /sw/include + /opt/local/include + ${KTX_ROOT} + DOC "The directory where KTX/ktx.h resides") - find_library( - KTX_LIBRARY - NAMES libktx${CMAKE_DEBUG_POSTFIX}.so - PATHS - /usr/include - /usr/local/include - /sw/include - /opt/local/include - ${KTX_ROOT} - DOC "The directory where KTX/libktx.so resides") + find_library( + KTX_LIBRARY + NAMES libktx${CMAKE_DEBUG_POSTFIX}.so + PATHS + /usr/include + /usr/local/include + /sw/include + /opt/local/include + ${KTX_ROOT} + DOC "The directory where KTX/libktx.so resides") endif() # Handle REQUIRD argument, define *_FOUND variable @@ -65,8 +74,9 @@ find_package_handle_standard_args(KTX DEFAULT_MSG KTX_INCLUDE_DIR KTX_LIBRARY) # Define KTX_LIBRARIES and KTX_INCLUDE_DIRS if (KTX_FOUND) - set(KTX_INCLUDE_DIRS ${KTX_INCLUDE_DIR}) - set(KTX_LIBRARIES ${KTX_LIBRARY}) + set(KTX_INCLUDE_DIRS ${KTX_INCLUDE_DIR}) + set(KTX_LIBRARIES ${KTX_LIBRARY}) + set(KTX_BINARIES ${KTX_BINARY}) endif() # Hide some variables diff --git a/cmake/FindSLANG.cmake b/cmake/FindSLANG.cmake index 63200b2..b9cd7be 100644 --- a/cmake/FindSLANG.cmake +++ b/cmake/FindSLANG.cmake @@ -73,7 +73,7 @@ find_package_handle_standard_args(SLANG DEFAULT_MSG SLANG_INCLUDE_DIR SLANG_LIBR # Define SLANG_LIBRARIES and SLANG_INCLUDE_DIRS if (SLANG_FOUND) - set(SLANG_BINARIES ${SLANG_BINARY} ${SLANG_GLSLANG}) + set(SLANG_BINARIES ${SLANG_BINARY}) set(SLANG_LIBRARIES ${SLANG_LIBRARY}) set(SLANG_INCLUDE_DIRS ${SLANG_INCLUDE_DIR}) endif() diff --git a/src/Engine/Containers/List.h b/src/Engine/Containers/List.h index 284ace2..2404f4d 100644 --- a/src/Engine/Containers/List.h +++ b/src/Engine/Containers/List.h @@ -287,9 +287,9 @@ public: return insertedElement; } // front + popFront - value_type&& retrieve() + value_type retrieve() { - auto&& temp = std::move(root->data); + value_type temp = std::move(root->data); popFront(); return std::move(temp); } diff --git a/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp b/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp index 5e81b27..2d09cd2 100644 --- a/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanAllocator.cpp @@ -133,57 +133,58 @@ void Allocation::markFree(SubAllocation *allocation) PSubAllocation allocHandle; PSubAllocation freeRangeToDelete; - std::unique_lock lck(lock); - //Join lower bound - for (auto freeRange : freeRanges) { - PSubAllocation freeAlloc = freeRange.value; - if (freeAlloc->allocatedOffset <= lowerBound - && freeAlloc->allocatedOffset + freeAlloc->allocatedSize >= upperBound) + std::unique_lock lck(lock); + //Join lower bound + for (auto freeRange : freeRanges) { - // allocation is already in a free region - return; + PSubAllocation freeAlloc = freeRange.value; + if (freeAlloc->allocatedOffset <= lowerBound + && freeAlloc->allocatedOffset + freeAlloc->allocatedSize >= upperBound) + { + // allocation is already in a free region + return; + } + if (freeAlloc->allocatedOffset + freeAlloc->allocatedSize == lowerBound) + { + //extend freeAlloc by the allocatedSize + freeAlloc->allocatedSize += allocation->allocatedSize; + allocHandle = freeAlloc; + break; + } } - if (freeAlloc->allocatedOffset + freeAlloc->allocatedSize == lowerBound) + //Join upper bound + auto foundAlloc = freeRanges.find(upperBound); + if (foundAlloc != freeRanges.end()) { - //extend freeAlloc by the allocatedSize - freeAlloc->allocatedSize += allocation->allocatedSize; - allocHandle = freeAlloc; - break; + freeRangeToDelete = foundAlloc->value; + // There is a free allocation ending where the new free one ends + if (allocHandle != nullptr) + { + // extend allocHandle by another foundAlloc->allocatedSize bytes + allocHandle->allocatedSize += foundAlloc->value->allocatedSize; + freeRanges.erase(foundAlloc->key); + } + else + { + // set foundAlloc back by size amount + allocHandle = foundAlloc->value; + allocHandle->allocatedOffset -= allocation->allocatedSize; + allocHandle->alignedOffset -= allocation->allocatedSize; + // place back at correct offset + freeRanges[allocHandle->allocatedOffset] = allocHandle; + // remove from offset map since key changes + freeRanges.erase(foundAlloc->key); + } } + + if (allocHandle == nullptr) + { + allocHandle = new SubAllocation(this, allocation->alignedOffset, allocation->size, allocation->alignedOffset, allocation->allocatedSize); + freeRanges[allocation->allocatedOffset] = allocHandle; + } + activeAllocations.erase(allocation->allocatedOffset); } - //Join upper bound - auto foundAlloc = freeRanges.find(upperBound); - if (foundAlloc != freeRanges.end()) - { - freeRangeToDelete = foundAlloc->value; - // There is a free allocation ending where the new free one ends - if (allocHandle != nullptr) - { - // extend allocHandle by another foundAlloc->allocatedSize bytes - allocHandle->allocatedSize += foundAlloc->value->allocatedSize; - freeRanges.erase(foundAlloc->key); - } - else - { - // set foundAlloc back by size amount - allocHandle = foundAlloc->value; - allocHandle->allocatedOffset -= allocation->allocatedSize; - allocHandle->alignedOffset -= allocation->allocatedSize; - // place back at correct offset - freeRanges[allocHandle->allocatedOffset] = allocHandle; - // remove from offset map since key changes - freeRanges.erase(foundAlloc->key); - } - } - - if (allocHandle == nullptr) - { - allocHandle = new SubAllocation(this, allocation->alignedOffset, allocation->size, allocation->alignedOffset, allocation->allocatedSize); - freeRanges[allocation->allocatedOffset] = allocHandle; - } - activeAllocations.erase(allocation->allocatedOffset); - lock.unlock(); bytesUsed -= allocation->allocatedSize; // TODO: delete allocation when bytesUsed == 0 } diff --git a/src/Engine/ThreadPool.cpp b/src/Engine/ThreadPool.cpp index 9a77084..122d234 100644 --- a/src/Engine/ThreadPool.cpp +++ b/src/Engine/ThreadPool.cpp @@ -47,25 +47,26 @@ ThreadPool::~ThreadPool() void ThreadPool::addJob(Job&& job) { std::unique_lock lock(jobQueueLock); + std::cout << "Adding job " << job.id << std::endl; jobQueue.add(std::move(job)); jobQueueCV.notify_one(); } void ThreadPool::addJob(MainJob&& job) { std::unique_lock lock(mainJobLock); - //std::cout << "Adding main job " << std::addressof(job.handle) << std::endl; + std::cout << "Adding main job " << job.id << std::endl; mainJobs.add(std::move(job)); mainJobCV.notify_one(); } void ThreadPool::enqueueWaiting(Event* event, Job&& job) { - //std::cout << job << " waiting for event " << event->name << std::endl; + std::cout << job.id << " waiting for event " << event->name << std::endl; std::unique_lock lock(waitingLock); waitingJobs[*event].add(std::move(job)); } void ThreadPool::enqueueWaiting(Event* event, MainJob&& job) { - //std::cout << std::addressof(job.handle) << " main waiting for event " << event->name << std::endl; + std::cout << job.id << " main waiting for event " << event->name << std::endl; std::unique_lock lock(waitingMainLock); waitingMainJobs[*event].add(std::move(job)); } @@ -76,8 +77,9 @@ void ThreadPool::notify(Event* event) std::unique_lock lock2(waitingLock); while(!waitingJobs[*event].empty()) { - //std::cout << "Waking up job " << job << std::endl; - jobQueue.add(std::move(waitingJobs[*event].retrieve())); + std::cout << "Waking up job " << waitingJobs[*event].front().id << std::endl; + Job job = std::move(waitingJobs[*event].retrieve()); + jobQueue.add(std::move(job)); jobQueueCV.notify_one(); } } @@ -86,37 +88,54 @@ void ThreadPool::notify(Event* event) std::unique_lock lock2(waitingMainLock); while(!waitingMainJobs[*event].empty()) { + std::cout << "Waking up main job " << waitingMainJobs[*event].front().id << std::endl; mainJobs.add(std::move(waitingMainJobs[*event].retrieve())); mainJobCV.notify_one(); } } } +void ThreadPool::tryMainJob() +{ + MainJob job; + { + std::unique_lock lock(mainJobLock); + if(!mainJobs.empty()) + { + job = std::move(mainJobs.retrieve()); + } + else + { + return; + } + } + job.resume(); +} void ThreadPool::threadLoop(const bool mainThread) { while(running.load()) { if(mainThread) { - std::unique_lock lock(mainJobLock); - if(!mainJobs.empty()) + tryMainJob(); + } + Job job; + { + std::unique_lock lock(jobQueueLock); + if(jobQueue.empty()) { - MainJob&& job = mainJobs.retrieve(); - lock.unlock(); - job.resume(); + jobQueueCV.wait(lock); + } + if(!jobQueue.empty()) + { + job = std::move(jobQueue.retrieve()); + } + else + { + continue; } } - std::unique_lock lock(jobQueueLock); - if(jobQueue.empty()) - { - jobQueueCV.wait(lock); - } - if(!jobQueue.empty()) - { - Job&& job = jobQueue.retrieve(); - lock.unlock(); - //std::cout << "Starting job " << job << std::endl; - job.resume(); - } + std::cout << "Starting job " << job.id << std::endl; + job.resume(); } } diff --git a/src/Engine/ThreadPool.h b/src/Engine/ThreadPool.h index ccac955..2198549 100644 --- a/src/Engine/ThreadPool.h +++ b/src/Engine/ThreadPool.h @@ -25,6 +25,7 @@ struct JobPromiseBase exit(1); }; }; +static std::atomic_uint64_t globalCounter; template struct JobBase { @@ -32,10 +33,13 @@ public: using promise_type = JobPromiseBase; explicit JobBase() + : id(-1) {} explicit JobBase(std::coroutine_handle handle) : handle(handle) + , id(globalCounter++) { + std::cout << "Creating job " << id << std::endl; /*if constexpr(MainJob) { std::cout << "Creating mainjob " << handle.address() << std::endl; @@ -48,13 +52,16 @@ public: JobBase(const JobBase & rhs) = delete; JobBase(JobBase&& rhs) : handle(std::move(rhs.handle)) + , id(std::move(rhs.id)) { + rhs.id = -1; rhs.handle = nullptr; } ~JobBase() { if(handle) { + std::cout << "Destroying job " << id << std::endl; handle.destroy(); } } @@ -64,6 +71,8 @@ public: if(this != &rhs) { handle = std::move(rhs.handle); + id = std::move(rhs.id); + rhs.id = -1; rhs.handle = nullptr; } return *this; @@ -73,6 +82,7 @@ public: handle.resume(); } std::coroutine_handle handle; + uint64 id; private: }; @@ -138,6 +148,7 @@ private: Map> waitingMainJobs; std::mutex waitingMainLock; + void tryMainJob(); void threadLoop(const bool isMainThread); };