Merge branch 'master' of https://github.com/Dynamitos/Seele
This commit is contained in:
Vendored
+2
-2
@@ -12,8 +12,8 @@
|
|||||||
"args": [],
|
"args": [],
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
"cwd": "${workspaceRoot}/bin/Debug",
|
"cwd": "${workspaceRoot}/bin/Debug",
|
||||||
|
"console": "internalConsole",
|
||||||
"environment": [],
|
"environment": [],
|
||||||
"externalConsole": false,
|
|
||||||
"symbolSearchPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.25.28610\\lib\\x64",
|
"symbolSearchPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.25.28610\\lib\\x64",
|
||||||
"requireExactSource": false,
|
"requireExactSource": false,
|
||||||
"logging": {
|
"logging": {
|
||||||
@@ -30,9 +30,9 @@
|
|||||||
"program": "${workspaceRoot}/bin/Debug/Seele_unit_tests.exe",
|
"program": "${workspaceRoot}/bin/Debug/Seele_unit_tests.exe",
|
||||||
"args": [],
|
"args": [],
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
|
"console": "internalConsole",
|
||||||
"cwd": "${workspaceRoot}/bin/Debug",
|
"cwd": "${workspaceRoot}/bin/Debug",
|
||||||
"environment": [],
|
"environment": [],
|
||||||
"externalConsole": false
|
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
+6
-5
@@ -1,6 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.15)
|
cmake_minimum_required(VERSION 3.19)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
|
||||||
# Handle superbuild first
|
# Handle superbuild first
|
||||||
option (USE_SUPERBUILD "Whether or not a superbuild should be invoked" ON)
|
option (USE_SUPERBUILD "Whether or not a superbuild should be invoked" ON)
|
||||||
@@ -27,6 +27,8 @@ 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_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/bin/Debug)
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/bin/Release)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/bin/Release)
|
||||||
|
|
||||||
|
add_compile_options($<$<CXX_COMPILER_ID:MSVC>:/MP>)
|
||||||
|
|
||||||
if (USE_SUPERBUILD)
|
if (USE_SUPERBUILD)
|
||||||
project (SUPERBUILD NONE)
|
project (SUPERBUILD NONE)
|
||||||
# execute the superbuild (this script will be invoked again without the
|
# execute the superbuild (this script will be invoked again without the
|
||||||
@@ -52,13 +54,12 @@ find_package(SLang REQUIRED)
|
|||||||
include_directories(${GLM_INCLUDE_DIRS})
|
include_directories(${GLM_INCLUDE_DIRS})
|
||||||
include_directories(${STB_INCLUDE_DIRS})
|
include_directories(${STB_INCLUDE_DIRS})
|
||||||
include_directories(${Vulkan_INCLUDE_DIR})
|
include_directories(${Vulkan_INCLUDE_DIR})
|
||||||
include_directories(${SPIRV_INCLUDE_DIRS})
|
#include_directories(${SPIRV_INCLUDE_DIRS})
|
||||||
include_directories(${Boost_INCLUDE_DIRS})
|
include_directories(${Boost_INCLUDE_DIRS})
|
||||||
include_directories(${GLFW_INCLUDE_DIRS})
|
include_directories(${GLFW_INCLUDE_DIRS})
|
||||||
include_directories(${SLANG_INCLUDE_DIRS})
|
include_directories(${SLANG_INCLUDE_DIRS})
|
||||||
include_directories(${ASSIMP_INCLUDE_DIRS})
|
include_directories(${ASSIMP_INCLUDE_DIRS})
|
||||||
include_directories(${JSON_INCLUDE_DIRS})
|
include_directories(${JSON_INCLUDE_DIRS})
|
||||||
include_directories(${SPIRV_INCLUDE_DIRS})
|
|
||||||
include_directories(${ENGINE_ROOT})
|
include_directories(${ENGINE_ROOT})
|
||||||
include_directories(src/Engine)
|
include_directories(src/Engine)
|
||||||
add_definitions(${Vulkan_DEFINITIONS})
|
add_definitions(${Vulkan_DEFINITIONS})
|
||||||
@@ -77,7 +78,7 @@ target_link_libraries(SeeleEngine ${GLFW_LIBRARIES})
|
|||||||
target_link_libraries(SeeleEngine ${SLANG_LIBRARIES})
|
target_link_libraries(SeeleEngine ${SLANG_LIBRARIES})
|
||||||
target_link_libraries(SeeleEngine ${ASSIMP_LIBRARIES})
|
target_link_libraries(SeeleEngine ${ASSIMP_LIBRARIES})
|
||||||
target_link_libraries(SeeleEngine ${JSON_LIBRARY})
|
target_link_libraries(SeeleEngine ${JSON_LIBRARY})
|
||||||
target_link_libraries(SeeleEngine ${SPIRV_LIBRARIES})
|
#target_link_libraries(SeeleEngine ${SPIRV_LIBRARIES})
|
||||||
|
|
||||||
#target_precompile_headers(SeeleEngine
|
#target_precompile_headers(SeeleEngine
|
||||||
# PRIVATE
|
# PRIVATE
|
||||||
|
|||||||
+4
-4
@@ -6,17 +6,17 @@
|
|||||||
"debug": {
|
"debug": {
|
||||||
"short": "Debug",
|
"short": "Debug",
|
||||||
"long": "Enable debugging and validation",
|
"long": "Enable debugging and validation",
|
||||||
"buildType": "Debug",
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"CMAKE_DEBUG_POSTFIX": "d"
|
"CMAKE_DEBUG_POSTFIX": "d",
|
||||||
|
"CMAKE_BUILD_TYPE": "Debug"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"release": {
|
"release": {
|
||||||
"short": "Release",
|
"short": "Release",
|
||||||
"long": "Optimize binary for speed",
|
"long": "Optimize binary for speed",
|
||||||
"buildType": "Release",
|
|
||||||
"settings": {
|
"settings": {
|
||||||
"CMAKE_DEBUG_POSTFIX": ""
|
"CMAKE_DEBUG_POSTFIX": "",
|
||||||
|
"CMAKE_BUILD_TYPE": "Release"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,8 @@ if (WIN32)
|
|||||||
NAMES assimp-vc${MSVC_TOOLSET_VERSION}-mt${CMAKE_DEBUG_POSTFIX}.lib
|
NAMES assimp-vc${MSVC_TOOLSET_VERSION}-mt${CMAKE_DEBUG_POSTFIX}.lib
|
||||||
PATHS
|
PATHS
|
||||||
$ENV{PROGRAMFILES}/lib
|
$ENV{PROGRAMFILES}/lib
|
||||||
${ASSIMP_ROOT}/lib/)
|
${ASSIMP_ROOT}/lib
|
||||||
|
${ASSIMP_ROOT}/lib/${CMAKE_BUILD_TYPE})
|
||||||
|
|
||||||
find_file(
|
find_file(
|
||||||
ASSIMP_BINARY
|
ASSIMP_BINARY
|
||||||
|
|||||||
+11
-8
@@ -5,8 +5,11 @@ set(EXTRA_CMAKE_ARGS)
|
|||||||
#------------ASSIMP---------------
|
#------------ASSIMP---------------
|
||||||
list(APPEND DEPENDENCIES assimp)
|
list(APPEND DEPENDENCIES assimp)
|
||||||
set(ASSIMP_BUILD_TESTS OFF CACHE INTERNAL "")
|
set(ASSIMP_BUILD_TESTS OFF CACHE INTERNAL "")
|
||||||
|
set(ASSIMP_BUILD_SAMPLES OFF CACHE INTERNAL "")
|
||||||
|
set(ASSIMP_BUILD_OVERALLS OFF CACHE INTERNAL "")
|
||||||
set(ASSIMP_BUILD_ASSIMP_TOOLS OFF CACHE INTERNAL "")
|
set(ASSIMP_BUILD_ASSIMP_TOOLS OFF CACHE INTERNAL "")
|
||||||
set(ASSIMP_INSTALL OFF CACHE INTERNAL "")
|
set(ASSIMP_INSTALL OFF CACHE INTERNAL "")
|
||||||
|
set(ASSIMP_BUILD_ZLIB OFF CACHE INTERNAL "")
|
||||||
set(BUILD_SHARED_LIBS ON CACHE INTERNAL "")
|
set(BUILD_SHARED_LIBS ON CACHE INTERNAL "")
|
||||||
|
|
||||||
add_subdirectory(${ASSIMP_ROOT} ${ASSIMP_ROOT})
|
add_subdirectory(${ASSIMP_ROOT} ${ASSIMP_ROOT})
|
||||||
@@ -74,14 +77,14 @@ ExternalProject_Add(slang
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
#----------------SPIR-V-CROSS--------------------
|
#----------------SPIR-V-CROSS--------------------
|
||||||
list(APPEND DEPENDENCIES spirv-cross-reflect)
|
# list(APPEND DEPENDENCIES spirv-cross-reflect)
|
||||||
set(SPIRV_CROSS_ENABLE_HLSL OFF CACHE BOOL "")
|
# set(SPIRV_CROSS_ENABLE_HLSL OFF CACHE BOOL "")
|
||||||
set(SPIRV_CROSS_ENABLE_TESTS OFF CACHE BOOL "")
|
# set(SPIRV_CROSS_ENABLE_TESTS OFF CACHE BOOL "")
|
||||||
set(SPIRV_CROSS_CLI OFF CACHE BOOL "")
|
# set(SPIRV_CROSS_CLI OFF CACHE BOOL "")
|
||||||
set(SPIRV_CROSS_ENABLE_C_API OFF CACHE BOOL "")
|
# set(SPIRV_CROSS_ENABLE_C_API OFF CACHE BOOL "")
|
||||||
set(SPIRV_CROSS_ENABLE_UTIL OFF CACHE BOOL "")
|
# set(SPIRV_CROSS_ENABLE_UTIL OFF CACHE BOOL "")
|
||||||
set(SPIRV_CROSS_SKIP_INSTALL ON CACHE BOOL "")
|
# set(SPIRV_CROSS_SKIP_INSTALL ON CACHE BOOL "")
|
||||||
add_subdirectory(${SPIRV_ROOT})
|
# add_subdirectory(${SPIRV_ROOT})
|
||||||
|
|
||||||
|
|
||||||
#-----------------SeeleEngine--------------------
|
#-----------------SeeleEngine--------------------
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
This file needs to be here because otherwise git will delete the folder and the engine can't automatically generate it
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
add_subdirectory(x64/)
|
||||||
@@ -29,8 +29,7 @@ MeshLoader::~MeshLoader()
|
|||||||
|
|
||||||
void MeshLoader::importAsset(const std::filesystem::path &path)
|
void MeshLoader::importAsset(const std::filesystem::path &path)
|
||||||
{
|
{
|
||||||
//futures.add(std::async(std::launch::async, &MeshLoader::import, this, path));
|
futures.add(std::async(std::launch::async, &MeshLoader::import, this, path));
|
||||||
import(path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshLoader::loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials, Gfx::PGraphics graphics)
|
void MeshLoader::loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials, Gfx::PGraphics graphics)
|
||||||
@@ -118,7 +117,7 @@ VertexStreamComponent createVertexStream(uint32 size, aiVector3D* sourceData, Gf
|
|||||||
vbInfo.vertexSize = sizeof(Vector);
|
vbInfo.vertexSize = sizeof(Vector);
|
||||||
vbInfo.resourceData.data = (uint8 *)buffer.data();
|
vbInfo.resourceData.data = (uint8 *)buffer.data();
|
||||||
vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
|
vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
|
||||||
vbInfo.resourceData.size = sizeof(Vector) * buffer.size();
|
vbInfo.resourceData.size = sizeof(Vector) * (uint32)buffer.size();
|
||||||
return VertexStreamComponent(graphics->createVertexBuffer(vbInfo), 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32B32_SFLOAT);
|
return VertexStreamComponent(graphics->createVertexBuffer(vbInfo), 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32B32_SFLOAT);
|
||||||
}
|
}
|
||||||
VertexStreamComponent createVertexStream(uint32 size, aiVector2D* sourceData, Gfx::PGraphics graphics)
|
VertexStreamComponent createVertexStream(uint32 size, aiVector2D* sourceData, Gfx::PGraphics graphics)
|
||||||
@@ -133,7 +132,7 @@ VertexStreamComponent createVertexStream(uint32 size, aiVector2D* sourceData, Gf
|
|||||||
vbInfo.vertexSize = sizeof(Vector2);
|
vbInfo.vertexSize = sizeof(Vector2);
|
||||||
vbInfo.resourceData.data = (uint8 *)buffer.data();
|
vbInfo.resourceData.data = (uint8 *)buffer.data();
|
||||||
vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
|
vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
|
||||||
vbInfo.resourceData.size = sizeof(Vector2) * buffer.size();
|
vbInfo.resourceData.size = sizeof(Vector2) * (uint32)buffer.size();
|
||||||
return VertexStreamComponent(graphics->createVertexBuffer(vbInfo), 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32_SFLOAT);
|
return VertexStreamComponent(graphics->createVertexBuffer(vbInfo), 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32_SFLOAT);
|
||||||
}
|
}
|
||||||
void MeshLoader::loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, const Array<PMaterialAsset>& materials, Gfx::PGraphics graphics)
|
void MeshLoader::loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, const Array<PMaterialAsset>& materials, Gfx::PGraphics graphics)
|
||||||
@@ -180,7 +179,7 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMesh
|
|||||||
idxInfo.indexType = Gfx::SE_INDEX_TYPE_UINT32;
|
idxInfo.indexType = Gfx::SE_INDEX_TYPE_UINT32;
|
||||||
idxInfo.resourceData.data = (uint8 *)indices.data();
|
idxInfo.resourceData.data = (uint8 *)indices.data();
|
||||||
idxInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
|
idxInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
|
||||||
idxInfo.resourceData.size = sizeof(uint32) * indices.size();
|
idxInfo.resourceData.size = sizeof(uint32) * (uint32)indices.size();
|
||||||
Gfx::PIndexBuffer indexBuffer = graphics->createIndexBuffer(idxInfo);
|
Gfx::PIndexBuffer indexBuffer = graphics->createIndexBuffer(idxInfo);
|
||||||
indexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS);
|
indexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS);
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ target_sources(SeeleEngine
|
|||||||
main.cpp)
|
main.cpp)
|
||||||
|
|
||||||
add_subdirectory(Asset/)
|
add_subdirectory(Asset/)
|
||||||
|
add_subdirectory(Arch/)
|
||||||
add_subdirectory(Containers/)
|
add_subdirectory(Containers/)
|
||||||
|
add_subdirectory(Fibers/)
|
||||||
add_subdirectory(Graphics/)
|
add_subdirectory(Graphics/)
|
||||||
add_subdirectory(Material/)
|
add_subdirectory(Material/)
|
||||||
add_subdirectory(Math/)
|
add_subdirectory(Math/)
|
||||||
|
|||||||
+125
-99
@@ -25,12 +25,12 @@ namespace Seele
|
|||||||
//std::memset(_data, 0, sizeof(T) * DEFAULT_ALLOC_SIZE);
|
//std::memset(_data, 0, sizeof(T) * DEFAULT_ALLOC_SIZE);
|
||||||
refreshIterators();
|
refreshIterators();
|
||||||
}
|
}
|
||||||
Array(uint32 size, T value = T())
|
Array(size_t size, T value = T())
|
||||||
: allocated(size), arraySize(size)
|
: allocated(size), arraySize(size)
|
||||||
{
|
{
|
||||||
_data = new T[size];
|
_data = new T[size];
|
||||||
assert(_data != nullptr);
|
assert(_data != nullptr);
|
||||||
for (uint32 i = 0; i < size; ++i)
|
for (size_t i = 0; i < size; ++i)
|
||||||
{
|
{
|
||||||
assert(i < size);
|
assert(i < size);
|
||||||
_data[i] = value;
|
_data[i] = value;
|
||||||
@@ -38,7 +38,7 @@ namespace Seele
|
|||||||
refreshIterators();
|
refreshIterators();
|
||||||
}
|
}
|
||||||
Array(std::initializer_list<T> init)
|
Array(std::initializer_list<T> init)
|
||||||
: allocated((uint32)init.size()), arraySize((uint32)init.size())
|
: allocated(init.size()), arraySize(init.size())
|
||||||
{
|
{
|
||||||
_data = new T[init.size()];
|
_data = new T[init.size()];
|
||||||
auto it = init.begin();
|
auto it = init.begin();
|
||||||
@@ -194,6 +194,17 @@ namespace Seele
|
|||||||
}
|
}
|
||||||
return endIt;
|
return endIt;
|
||||||
}
|
}
|
||||||
|
Iterator find(T&& item)
|
||||||
|
{
|
||||||
|
for (uint32 i = 0; i < arraySize; ++i)
|
||||||
|
{
|
||||||
|
if (_data[i] == item)
|
||||||
|
{
|
||||||
|
return Iterator(&_data[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return endIt;
|
||||||
|
}
|
||||||
Iterator begin() const
|
Iterator begin() const
|
||||||
{
|
{
|
||||||
return beginIt;
|
return beginIt;
|
||||||
@@ -215,11 +226,11 @@ namespace Seele
|
|||||||
{
|
{
|
||||||
if (arraySize == allocated)
|
if (arraySize == allocated)
|
||||||
{
|
{
|
||||||
uint32 newSize = arraySize + 1;
|
size_t newSize = arraySize + 1;
|
||||||
allocated = calculateGrowth(newSize);
|
allocated = calculateGrowth(newSize);
|
||||||
T *tempArray = new T[allocated];
|
T *tempArray = new T[allocated];
|
||||||
assert(tempArray != nullptr);
|
assert(tempArray != nullptr);
|
||||||
for (uint32 i = 0; i < arraySize; ++i)
|
for (size_t i = 0; i < arraySize; ++i)
|
||||||
{
|
{
|
||||||
tempArray[i] = _data[i];
|
tempArray[i] = _data[i];
|
||||||
}
|
}
|
||||||
@@ -230,6 +241,25 @@ namespace Seele
|
|||||||
refreshIterators();
|
refreshIterators();
|
||||||
return _data[arraySize - 1];
|
return _data[arraySize - 1];
|
||||||
}
|
}
|
||||||
|
T &add(T&& item)
|
||||||
|
{
|
||||||
|
if (arraySize == allocated)
|
||||||
|
{
|
||||||
|
size_t newSize = arraySize + 1;
|
||||||
|
allocated = calculateGrowth(newSize);
|
||||||
|
T *tempArray = new T[allocated];
|
||||||
|
assert(tempArray != nullptr);
|
||||||
|
for (size_t i = 0; i < arraySize; ++i)
|
||||||
|
{
|
||||||
|
tempArray[i] = std::move(_data[i]);
|
||||||
|
}
|
||||||
|
delete[] _data;
|
||||||
|
_data = tempArray;
|
||||||
|
}
|
||||||
|
_data[arraySize++] = std::move(item);
|
||||||
|
refreshIterators();
|
||||||
|
return _data[arraySize - 1];
|
||||||
|
}
|
||||||
T &addUnique(const T &item = T())
|
T &addUnique(const T &item = T())
|
||||||
{
|
{
|
||||||
Iterator it;
|
Iterator it;
|
||||||
@@ -240,22 +270,22 @@ namespace Seele
|
|||||||
return add(item);
|
return add(item);
|
||||||
}
|
}
|
||||||
template<typename... args>
|
template<typename... args>
|
||||||
T &emplace(args...)
|
T &emplace(args... arguments)
|
||||||
{
|
{
|
||||||
if (arraySize == allocated)
|
if (arraySize == allocated)
|
||||||
{
|
{
|
||||||
uint32 newSize = arraySize + 1;
|
size_t newSize = arraySize + 1;
|
||||||
allocated = calculateGrowth(newSize);
|
allocated = calculateGrowth(newSize);
|
||||||
T *tempArray = new T[allocated];
|
T *tempArray = new T[allocated];
|
||||||
assert(tempArray != nullptr);
|
assert(tempArray != nullptr);
|
||||||
for (uint32 i = 0; i < arraySize; ++i)
|
for (size_t i = 0; i < arraySize; ++i)
|
||||||
{
|
{
|
||||||
tempArray[i] = _data[i];
|
tempArray[i] = _data[i];
|
||||||
}
|
}
|
||||||
delete[] _data;
|
delete[] _data;
|
||||||
_data = tempArray;
|
_data = tempArray;
|
||||||
}
|
}
|
||||||
_data[arraySize++] = T(args...);
|
_data[arraySize++] = T(arguments...);
|
||||||
refreshIterators();
|
refreshIterators();
|
||||||
return _data[arraySize - 1];
|
return _data[arraySize - 1];
|
||||||
}
|
}
|
||||||
@@ -271,7 +301,7 @@ namespace Seele
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_data[index] = _data[arraySize - 1];
|
_data[index] = std::move(_data[arraySize - 1]);
|
||||||
}
|
}
|
||||||
arraySize--;
|
arraySize--;
|
||||||
}
|
}
|
||||||
@@ -283,7 +313,7 @@ namespace Seele
|
|||||||
allocated = 0;
|
allocated = 0;
|
||||||
refreshIterators();
|
refreshIterators();
|
||||||
}
|
}
|
||||||
void resize(uint32 newSize)
|
void resize(size_t newSize)
|
||||||
{
|
{
|
||||||
if (newSize < allocated)
|
if (newSize < allocated)
|
||||||
{
|
{
|
||||||
@@ -301,27 +331,31 @@ namespace Seele
|
|||||||
}
|
}
|
||||||
refreshIterators();
|
refreshIterators();
|
||||||
}
|
}
|
||||||
inline uint32 indexOf(Iterator iterator)
|
inline size_t indexOf(Iterator iterator)
|
||||||
{
|
{
|
||||||
return iterator - beginIt;
|
return iterator - beginIt;
|
||||||
}
|
}
|
||||||
inline uint32 indexOf(ConstIterator iterator) const
|
inline size_t indexOf(ConstIterator iterator) const
|
||||||
{
|
{
|
||||||
return iterator.p - beginIt.p;
|
return iterator.p - beginIt.p;
|
||||||
}
|
}
|
||||||
inline uint32 indexOf(T& t)
|
inline size_t indexOf(T& t)
|
||||||
{
|
{
|
||||||
return indexOf(find(t));
|
return indexOf(find(t));
|
||||||
}
|
}
|
||||||
inline uint32 indexOf(const T& t) const
|
inline size_t indexOf(const T& t) const
|
||||||
{
|
{
|
||||||
return indexOf(find(t));
|
return indexOf(find(t));
|
||||||
}
|
}
|
||||||
inline uint32 size() const
|
inline size_t size() const
|
||||||
{
|
{
|
||||||
return arraySize;
|
return arraySize;
|
||||||
}
|
}
|
||||||
inline uint32 capacity() const
|
inline size_t empty() const
|
||||||
|
{
|
||||||
|
return arraySize == 0;
|
||||||
|
}
|
||||||
|
inline size_t capacity() const
|
||||||
{
|
{
|
||||||
return allocated;
|
return allocated;
|
||||||
}
|
}
|
||||||
@@ -338,44 +372,27 @@ namespace Seele
|
|||||||
arraySize--;
|
arraySize--;
|
||||||
refreshIterators();
|
refreshIterators();
|
||||||
}
|
}
|
||||||
T &operator[](uint32 index)
|
T &operator[](size_t index)
|
||||||
{
|
{
|
||||||
assert(index < arraySize);
|
assert(index < arraySize);
|
||||||
return _data[index];
|
return _data[index];
|
||||||
}
|
}
|
||||||
inline T &operator[](size_t index)
|
const T &operator[](size_t index) const
|
||||||
{
|
|
||||||
return this->operator[]((uint32)index);
|
|
||||||
}
|
|
||||||
inline T &operator[](int32 index)
|
|
||||||
{
|
|
||||||
return this->operator[]((uint32)index);
|
|
||||||
}
|
|
||||||
const T &operator[](uint32 index) const
|
|
||||||
{
|
{
|
||||||
assert(index < arraySize);
|
assert(index < arraySize);
|
||||||
return _data[index];
|
return _data[index];
|
||||||
}
|
}
|
||||||
inline const T &operator[](size_t index) const
|
|
||||||
{
|
|
||||||
return this->operator[]((uint32)index);
|
|
||||||
}
|
|
||||||
inline const T &operator[](int32 index) const
|
|
||||||
{
|
|
||||||
return this->operator[]((uint32)index);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32 calculateGrowth(uint32 newSize) const
|
size_t calculateGrowth(size_t newSize) const
|
||||||
{
|
{
|
||||||
const uint32 oldCapacity = capacity();
|
const size_t oldCapacity = capacity();
|
||||||
|
|
||||||
if (oldCapacity > UINT32_MAX - oldCapacity / 2)
|
if (oldCapacity > SIZE_MAX - oldCapacity / 2)
|
||||||
{
|
{
|
||||||
return newSize; // geometric growth would overflow
|
return newSize; // geometric growth would overflow
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32 geometric = oldCapacity + oldCapacity / 2;
|
const size_t geometric = oldCapacity + oldCapacity / 2;
|
||||||
|
|
||||||
if (geometric < newSize)
|
if (geometric < newSize)
|
||||||
{
|
{
|
||||||
@@ -395,71 +412,30 @@ namespace Seele
|
|||||||
{
|
{
|
||||||
ar & arraySize;
|
ar & arraySize;
|
||||||
ar & allocated;
|
ar & allocated;
|
||||||
for(uint32 i = 0; i < arraySize; ++i)
|
for(size_t i = 0; i < arraySize; ++i)
|
||||||
ar & _data[i];
|
ar & _data[i];
|
||||||
refreshIterators();
|
refreshIterators();
|
||||||
}
|
}
|
||||||
uint32 arraySize;
|
size_t arraySize;
|
||||||
uint32 allocated;
|
size_t allocated;
|
||||||
Iterator beginIt;
|
Iterator beginIt;
|
||||||
Iterator endIt;
|
Iterator endIt;
|
||||||
T *_data;
|
T *_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, uint32 N>
|
template <typename T, size_t N>
|
||||||
struct StaticArray
|
struct StaticArray
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StaticArray()
|
|
||||||
{
|
|
||||||
beginIt = Iterator(_data);
|
|
||||||
endIt = Iterator(_data + N);
|
|
||||||
}
|
|
||||||
StaticArray(T value)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < N; ++i)
|
|
||||||
{
|
|
||||||
_data[i] = value;
|
|
||||||
}
|
|
||||||
beginIt = Iterator(_data);
|
|
||||||
endIt = Iterator(_data + N);
|
|
||||||
}
|
|
||||||
~StaticArray()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint32 size() const
|
|
||||||
{
|
|
||||||
return N;
|
|
||||||
}
|
|
||||||
inline T *data()
|
|
||||||
{
|
|
||||||
return _data;
|
|
||||||
}
|
|
||||||
inline const T *data() const
|
|
||||||
{
|
|
||||||
return _data;
|
|
||||||
}
|
|
||||||
T &operator[](int index)
|
|
||||||
{
|
|
||||||
assert(index >= 0 && index < N);
|
|
||||||
return _data[index];
|
|
||||||
}
|
|
||||||
const T &operator[](int index) const
|
|
||||||
{
|
|
||||||
assert(index >= 0 && index < N);
|
|
||||||
return _data[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename X>
|
template <typename X>
|
||||||
class IteratorBase
|
class IteratorBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::forward_iterator_tag iterator_category;
|
using iterator_category = std::forward_iterator_tag;
|
||||||
typedef X value_type;
|
using value_type = X;
|
||||||
typedef std::ptrdiff_t difference_type;
|
using difference_type = std::ptrdiff_t;
|
||||||
typedef X &reference;
|
using reference = X&;
|
||||||
typedef X *pointer;
|
using pointer = X*;
|
||||||
|
|
||||||
IteratorBase(X *x = nullptr)
|
IteratorBase(X *x = nullptr)
|
||||||
: p(x)
|
: p(x)
|
||||||
@@ -500,36 +476,86 @@ namespace Seele
|
|||||||
private:
|
private:
|
||||||
X *p;
|
X *p;
|
||||||
};
|
};
|
||||||
typedef IteratorBase<T> Iterator;
|
using value_type = T;
|
||||||
typedef IteratorBase<const T> ConstIterator;
|
using size_type = size_t;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using pointer = T*;
|
||||||
|
using const_pointer = const T*;
|
||||||
|
using reference = T&;
|
||||||
|
using const_reference = const T&;
|
||||||
|
|
||||||
Iterator begin()
|
using iterator = IteratorBase<T>;
|
||||||
|
using const_iterator = IteratorBase<const T>;
|
||||||
|
|
||||||
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||||
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||||
|
|
||||||
|
StaticArray()
|
||||||
|
{
|
||||||
|
beginIt = iterator(_data);
|
||||||
|
endIt = iterator(_data + N);
|
||||||
|
}
|
||||||
|
StaticArray(T value)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < N; ++i)
|
||||||
|
{
|
||||||
|
_data[i] = value;
|
||||||
|
}
|
||||||
|
beginIt = iterator(_data);
|
||||||
|
endIt = iterator(_data + N);
|
||||||
|
}
|
||||||
|
~StaticArray()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_type size() const
|
||||||
|
{
|
||||||
|
return N;
|
||||||
|
}
|
||||||
|
inline pointer data()
|
||||||
|
{
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
inline const_pointer data() const
|
||||||
|
{
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
constexpr reference operator[](size_type index) noexcept
|
||||||
|
{
|
||||||
|
assert(index >= 0 && index < N);
|
||||||
|
return _data[index];
|
||||||
|
}
|
||||||
|
constexpr const_reference operator[](size_type index) const noexcept
|
||||||
|
{
|
||||||
|
assert(index >= 0 && index < N);
|
||||||
|
return _data[index];
|
||||||
|
}
|
||||||
|
iterator begin()
|
||||||
{
|
{
|
||||||
return beginIt;
|
return beginIt;
|
||||||
}
|
}
|
||||||
Iterator end()
|
iterator end()
|
||||||
{
|
{
|
||||||
return endIt;
|
return endIt;
|
||||||
}
|
}
|
||||||
ConstIterator begin() const
|
const_iterator begin() const
|
||||||
{
|
{
|
||||||
return beginIt;
|
return beginIt;
|
||||||
}
|
}
|
||||||
ConstIterator end() const
|
const_iterator end() const
|
||||||
{
|
{
|
||||||
return beginIt;
|
return beginIt;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
T _data[N];
|
T _data[N];
|
||||||
Iterator beginIt;
|
iterator beginIt;
|
||||||
Iterator endIt;
|
iterator endIt;
|
||||||
friend class boost::serialization::access;
|
friend class boost::serialization::access;
|
||||||
template<class Archive>
|
template<class Archive>
|
||||||
void serialize(Archive& ar, const unsigned int version)
|
void serialize(Archive& ar, const unsigned int version)
|
||||||
{
|
{
|
||||||
ar & N;
|
ar & N;
|
||||||
ar & _data;
|
ar & _data;
|
||||||
refreshIterators();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
@@ -250,6 +250,14 @@ public:
|
|||||||
refreshIterators();
|
refreshIterators();
|
||||||
return Iterator(next);
|
return Iterator(next);
|
||||||
}
|
}
|
||||||
|
void popBack()
|
||||||
|
{
|
||||||
|
remove(Iterator(tail->prev));
|
||||||
|
}
|
||||||
|
void popFront()
|
||||||
|
{
|
||||||
|
remove(Iterator(root));
|
||||||
|
}
|
||||||
Iterator insert(Iterator pos, const T &value)
|
Iterator insert(Iterator pos, const T &value)
|
||||||
{
|
{
|
||||||
_size++;
|
_size++;
|
||||||
|
|||||||
+53
-23
@@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <utility>
|
||||||
#include "Array.h"
|
#include "Array.h"
|
||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
@@ -9,12 +10,15 @@ struct Pair
|
|||||||
public:
|
public:
|
||||||
Pair()
|
Pair()
|
||||||
: key(K()), value(V())
|
: key(K()), value(V())
|
||||||
{
|
{}
|
||||||
}
|
template<class KeyType>
|
||||||
Pair(K key, V value)
|
explicit Pair(KeyType&& key)
|
||||||
: key(key), value(value)
|
: key(key), value(V())
|
||||||
{
|
{}
|
||||||
}
|
template<class KeyType, class ValueType>
|
||||||
|
explicit Pair(KeyType&& key, ValueType&& value)
|
||||||
|
: key(std::move(key)), value(std::move(value))
|
||||||
|
{}
|
||||||
K key;
|
K key;
|
||||||
V value;
|
V value;
|
||||||
};
|
};
|
||||||
@@ -28,11 +32,12 @@ private:
|
|||||||
Node *leftChild;
|
Node *leftChild;
|
||||||
Node *rightChild;
|
Node *rightChild;
|
||||||
Node()
|
Node()
|
||||||
: leftChild(nullptr), rightChild(nullptr), pair(K(), V())
|
: leftChild(nullptr), rightChild(nullptr), pair()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
Node(const K &key)
|
template<class KeyType, class ValueType>
|
||||||
: leftChild(nullptr), rightChild(nullptr), pair(key, V())
|
explicit Node(KeyType&& key, ValueType&& value)
|
||||||
|
: leftChild(nullptr), rightChild(nullptr), pair(key, value)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
Node(const Node& other)
|
Node(const Node& other)
|
||||||
@@ -242,7 +247,7 @@ public:
|
|||||||
Iterator operator--(int)
|
Iterator operator--(int)
|
||||||
{
|
{
|
||||||
Iterator tmp(*this);
|
Iterator tmp(*this);
|
||||||
++*this;
|
--*this;
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
Iterator operator++(int)
|
Iterator operator++(int)
|
||||||
@@ -256,7 +261,6 @@ public:
|
|||||||
Node *node;
|
Node *node;
|
||||||
Array<Node *> traversal;
|
Array<Node *> traversal;
|
||||||
};
|
};
|
||||||
|
|
||||||
V &operator[](const K& key)
|
V &operator[](const K& key)
|
||||||
{
|
{
|
||||||
root = splay(root, key);
|
root = splay(root, key);
|
||||||
@@ -268,6 +272,17 @@ public:
|
|||||||
}
|
}
|
||||||
return root->pair.value;
|
return root->pair.value;
|
||||||
}
|
}
|
||||||
|
V &operator[](K&& key)
|
||||||
|
{
|
||||||
|
root = splay(root, std::forward<K>(key));
|
||||||
|
if (root == nullptr || root->pair.key < key || key < root->pair.key)
|
||||||
|
{
|
||||||
|
root = insert(root, std::forward<K>(key));
|
||||||
|
_size++;
|
||||||
|
refreshIterators();
|
||||||
|
}
|
||||||
|
return root->pair.value;
|
||||||
|
}
|
||||||
Iterator find(const K& key)
|
Iterator find(const K& key)
|
||||||
{
|
{
|
||||||
root = splay(root, key);
|
root = splay(root, key);
|
||||||
@@ -277,12 +292,27 @@ public:
|
|||||||
}
|
}
|
||||||
return Iterator(root);
|
return Iterator(root);
|
||||||
}
|
}
|
||||||
|
Iterator find(K&& key)
|
||||||
|
{
|
||||||
|
root = splay(root, std::move(key));
|
||||||
|
if (root == nullptr || root->pair.key != key)
|
||||||
|
{
|
||||||
|
return endIt;
|
||||||
|
}
|
||||||
|
return Iterator(root);
|
||||||
|
}
|
||||||
Iterator erase(const K& key)
|
Iterator erase(const K& key)
|
||||||
{
|
{
|
||||||
root = remove(root, key);
|
root = remove(root, key);
|
||||||
refreshIterators();
|
refreshIterators();
|
||||||
return Iterator(root);
|
return Iterator(root);
|
||||||
}
|
}
|
||||||
|
Iterator erase(K&& key)
|
||||||
|
{
|
||||||
|
root = remove(root, std::move(key));
|
||||||
|
refreshIterators();
|
||||||
|
return Iterator(root);
|
||||||
|
}
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
delete root;
|
delete root;
|
||||||
@@ -290,9 +320,9 @@ public:
|
|||||||
_size = 0;
|
_size = 0;
|
||||||
refreshIterators();
|
refreshIterators();
|
||||||
}
|
}
|
||||||
bool exists(const K &key)
|
bool exists(K&& key)
|
||||||
{
|
{
|
||||||
return find(key) != endIt;
|
return find(std::forward<K>(key)) != endIt;
|
||||||
}
|
}
|
||||||
Iterator begin() const
|
Iterator begin() const
|
||||||
{
|
{
|
||||||
@@ -365,21 +395,19 @@ private:
|
|||||||
y->leftChild = node;
|
y->leftChild = node;
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
Node *makeNode(const K &key)
|
template<class KeyType>
|
||||||
{
|
Node *insert(Node *r, KeyType&& key)
|
||||||
return new Node(key);
|
|
||||||
}
|
|
||||||
Node *insert(Node *r, const K &key)
|
|
||||||
{
|
{
|
||||||
if (r == nullptr)
|
if (r == nullptr)
|
||||||
return makeNode(key);
|
{
|
||||||
|
return new Node(std::forward<KeyType>(key), V());
|
||||||
|
}
|
||||||
r = splay(r, key);
|
r = splay(r, key);
|
||||||
|
|
||||||
if (!(r->pair.key < key || key < r->pair.key))
|
if (!(r->pair.key < key || key < r->pair.key))
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
Node *newNode = makeNode(key);
|
Node *newNode = new Node(std::forward<KeyType>(key), V());
|
||||||
|
|
||||||
if (key < r->pair.key)
|
if (key < r->pair.key)
|
||||||
{
|
{
|
||||||
@@ -395,7 +423,8 @@ private:
|
|||||||
}
|
}
|
||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
Node *remove(Node *r, const K &key)
|
template<class KeyType>
|
||||||
|
Node *remove(Node *r, KeyType&& key)
|
||||||
{
|
{
|
||||||
Node *temp;
|
Node *temp;
|
||||||
if (!r)
|
if (!r)
|
||||||
@@ -424,7 +453,8 @@ private:
|
|||||||
delete temp;
|
delete temp;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
Node *splay(Node *r, const K &key)
|
template<class KeyType>
|
||||||
|
Node *splay(Node *r, KeyType&& key)
|
||||||
{
|
{
|
||||||
if (r == nullptr || !(r->pair.key < key || key < r->pair.key))
|
if (r == nullptr || !(r->pair.key < key || key < r->pair.key))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
target_sources(SeeleEngine
|
||||||
|
PRIVATE
|
||||||
|
Fibers.h
|
||||||
|
Fibers.cpp
|
||||||
|
JobQueue.h
|
||||||
|
JobQueue.cpp)
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#include "Fibers.h"
|
||||||
|
|
||||||
|
using namespace Seele;
|
||||||
|
using namespace Seele::Fibers;
|
||||||
|
|
||||||
|
std::atomic_uint64_t FiberJob::jobIDGenerator;
|
||||||
|
|
||||||
|
Counter::Counter()
|
||||||
|
{
|
||||||
|
count.store(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Counter::Counter(uint64 initialValue)
|
||||||
|
{
|
||||||
|
count.store(initialValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
Counter::~Counter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AwaitCounter&& FiberTask::promise_type::await_transform(AwaitCounter&& awaitCounter)
|
||||||
|
{
|
||||||
|
counter = awaitCounter.counter;
|
||||||
|
target = awaitCounter.target;
|
||||||
|
priority = awaitCounter.priority;
|
||||||
|
return std::move(awaitCounter);
|
||||||
|
}
|
||||||
|
|
||||||
|
FiberJob::FiberJob()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FiberJob::~FiberJob()
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,205 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "MinimalEngine.h"
|
||||||
|
#include "JobQueue.h"
|
||||||
|
#include <atomic>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace Seele
|
||||||
|
{
|
||||||
|
namespace Fibers
|
||||||
|
{
|
||||||
|
class Counter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Counter();
|
||||||
|
Counter(uint64 initialValue);
|
||||||
|
~Counter();
|
||||||
|
inline void increment()
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
inline void decrement()
|
||||||
|
{
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
inline void setValue(uint64 value)
|
||||||
|
{
|
||||||
|
count.store(value);
|
||||||
|
}
|
||||||
|
inline uint64 getValue()
|
||||||
|
{
|
||||||
|
return count.load();
|
||||||
|
}
|
||||||
|
inline bool greaterEqual(uint64 target)
|
||||||
|
{
|
||||||
|
return count.load() >= target;
|
||||||
|
}
|
||||||
|
inline bool greaterThan(uint64 target)
|
||||||
|
{
|
||||||
|
return count.load() > target;
|
||||||
|
}
|
||||||
|
inline bool lessEqual(uint64 target)
|
||||||
|
{
|
||||||
|
return count.load() <= target;
|
||||||
|
}
|
||||||
|
inline bool lessThan(uint64 target)
|
||||||
|
{
|
||||||
|
return count.load() < target;
|
||||||
|
}
|
||||||
|
inline bool equals(uint64 target)
|
||||||
|
{
|
||||||
|
return count.load() == target;
|
||||||
|
}
|
||||||
|
friend std::strong_ordering operator<=>(const Counter& counter, uint64 other)
|
||||||
|
{
|
||||||
|
return counter.count.load() <=> other;
|
||||||
|
}
|
||||||
|
friend std::ostream& operator<<(std::ostream& stream, const Counter* counter)
|
||||||
|
{
|
||||||
|
stream << counter->count;
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
friend std::ostream& operator<<(std::ostream& stream, PCounter counter)
|
||||||
|
{
|
||||||
|
stream << counter->count;
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::atomic_uint64_t count;
|
||||||
|
};
|
||||||
|
DEFINE_REF(Counter);
|
||||||
|
struct AwaitCounter
|
||||||
|
{
|
||||||
|
PCounter counter;
|
||||||
|
uint64 target;
|
||||||
|
JobPriority priority = JobPriority::MEDIUM;
|
||||||
|
bool await_ready() { return counter->greaterEqual(target); }
|
||||||
|
void await_suspend(std::coroutine_handle<> h) {
|
||||||
|
}
|
||||||
|
void await_resume() {}
|
||||||
|
};
|
||||||
|
struct AwaitCounter;
|
||||||
|
class FiberTask
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct promise_type;
|
||||||
|
using handle_type = std::coroutine_handle<promise_type>;
|
||||||
|
private:
|
||||||
|
promise_type* promise;
|
||||||
|
public:
|
||||||
|
FiberTask() = default;
|
||||||
|
explicit FiberTask(promise_type* promise)
|
||||||
|
: promise(promise) {}
|
||||||
|
FiberTask(const FiberTask& other)
|
||||||
|
: promise(other.promise) {}
|
||||||
|
FiberTask(FiberTask&& other)
|
||||||
|
: promise(std::move(other.promise)) {}
|
||||||
|
FiberTask& operator=(const FiberTask& other)
|
||||||
|
{
|
||||||
|
promise = other.promise;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
FiberTask& operator=(FiberTask&& other)
|
||||||
|
{
|
||||||
|
promise = std::move(other.promise);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline void resume() { promise->resume(); }
|
||||||
|
inline void destroy() { promise->destroy(); }
|
||||||
|
inline bool done() { return promise->done(); }
|
||||||
|
inline PCounter getCounter() const { return promise->counter; }
|
||||||
|
inline uint64 getTarget() const { return promise->target; }
|
||||||
|
inline JobPriority getPriority() const { return promise->priority; }
|
||||||
|
struct promise_type
|
||||||
|
{
|
||||||
|
promise_type()
|
||||||
|
{
|
||||||
|
handle = handle_type::from_promise(*this);
|
||||||
|
}
|
||||||
|
~promise_type() = default;
|
||||||
|
promise_type(const promise_type&) = delete;
|
||||||
|
promise_type(promise_type&&) = delete;
|
||||||
|
promise_type &operator=(const promise_type&) = delete;
|
||||||
|
promise_type &operator=(promise_type&&) = delete;
|
||||||
|
FiberTask get_return_object()
|
||||||
|
{
|
||||||
|
return FiberTask(this);
|
||||||
|
}
|
||||||
|
auto initial_suspend() { return std::suspend_never{}; }
|
||||||
|
auto final_suspend() noexcept { return std::suspend_always{}; }
|
||||||
|
auto return_void() {}
|
||||||
|
void unhandled_exception() { std::exit(1); }
|
||||||
|
AwaitCounter&& await_transform(AwaitCounter&& awaitCounter);
|
||||||
|
inline void resume() { handle.resume(); }
|
||||||
|
inline void destroy() { handle.destroy(); }
|
||||||
|
inline bool done() { return handle.done(); }
|
||||||
|
private:
|
||||||
|
handle_type handle;
|
||||||
|
PCounter counter;
|
||||||
|
uint64 target;
|
||||||
|
JobPriority priority;
|
||||||
|
friend class FiberTask;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
class FiberJob
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FiberJob();
|
||||||
|
template<typename func, typename... args>
|
||||||
|
FiberJob(PCounter counter, func function, args... arg)
|
||||||
|
: counter(counter), function(std::bind(function, arg...))
|
||||||
|
{
|
||||||
|
jobID = jobIDGenerator.fetch_add(1);
|
||||||
|
}
|
||||||
|
template<typename func, typename...args>
|
||||||
|
FiberJob(PCounter counter, JobPriority priority, func function, args... arg)
|
||||||
|
: counter(counter), priority(priority), function(std::bind(function, arg...))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
FiberJob(const FiberJob& other) = delete;
|
||||||
|
FiberJob(FiberJob&& other)
|
||||||
|
: counter(std::move(other.counter))
|
||||||
|
, jobID(std::move(other.jobID))
|
||||||
|
, priority(std::move(other.priority))
|
||||||
|
, function(std::move(other.function))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
~FiberJob();
|
||||||
|
FiberJob& operator=(const FiberJob& other) = delete;
|
||||||
|
FiberJob& operator=(FiberJob&& other)
|
||||||
|
{
|
||||||
|
if(this != &other)
|
||||||
|
{
|
||||||
|
counter = std::move(other.counter);
|
||||||
|
jobID = std::move(other.jobID);
|
||||||
|
priority = std::move(other.priority);
|
||||||
|
function = std::move(other.function);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
void operator()()
|
||||||
|
{
|
||||||
|
FiberTask task = function();
|
||||||
|
if(!task.done())
|
||||||
|
{
|
||||||
|
JobQueue::suspendJob(std::move(task));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
counter->increment();
|
||||||
|
task.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline JobPriority getPriority()
|
||||||
|
{
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
PCounter counter;
|
||||||
|
uint64 jobID;
|
||||||
|
static std::atomic_uint64_t jobIDGenerator;
|
||||||
|
JobPriority priority = JobPriority::MEDIUM;
|
||||||
|
std::function<FiberTask()> function;
|
||||||
|
};
|
||||||
|
} // namespace Fibers
|
||||||
|
} // namespace Seele
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
#include "JobQueue.h"
|
||||||
|
#include "Fibers.h"
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <processthreadsapi.h>
|
||||||
|
|
||||||
|
using namespace Seele;
|
||||||
|
using namespace Seele::Fibers;
|
||||||
|
|
||||||
|
std::wstring toString(JobPriority priority)
|
||||||
|
{
|
||||||
|
switch (priority)
|
||||||
|
{
|
||||||
|
case JobPriority::HIGH:
|
||||||
|
return L"HIGH";
|
||||||
|
case JobPriority::MEDIUM:
|
||||||
|
return L"MEDIUM";
|
||||||
|
case JobPriority::LOW:
|
||||||
|
return L"LOW";
|
||||||
|
case JobPriority::IO:
|
||||||
|
return L"IO";
|
||||||
|
default:
|
||||||
|
return L"Illegal Priority";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Array<JobQueue*> JobQueue::workers;
|
||||||
|
StaticArray<JobPriorityInfo, (size_t)JobPriority::NUM_PRIORITIES> JobQueue::priorityQueues;
|
||||||
|
|
||||||
|
JobQueue::JobQueue(JobPriority priority)
|
||||||
|
: priority(priority)
|
||||||
|
{
|
||||||
|
threadHandle = std::thread(&JobQueue::work, this);
|
||||||
|
SetThreadDescription(threadHandle.native_handle(), toString(priority).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
JobQueue::~JobQueue()
|
||||||
|
{
|
||||||
|
running = false;
|
||||||
|
threadHandle.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
void JobQueue::initJobQueues()
|
||||||
|
{
|
||||||
|
// TODO: make this dependent on actual cores
|
||||||
|
JobPriority priorities[16] = {
|
||||||
|
JobPriority::IO, JobPriority::IO,
|
||||||
|
JobPriority::LOW, JobPriority::LOW, JobPriority::LOW, JobPriority::LOW,
|
||||||
|
JobPriority::MEDIUM, JobPriority::MEDIUM, JobPriority::MEDIUM, JobPriority::MEDIUM, JobPriority::MEDIUM,
|
||||||
|
JobPriority::HIGH, JobPriority::HIGH, JobPriority::HIGH, JobPriority::HIGH, JobPriority::HIGH};
|
||||||
|
|
||||||
|
for(uint32 i = 0; i < 16; ++i)
|
||||||
|
{
|
||||||
|
workers.add(new JobQueue(priorities[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void JobQueue::cleanupJobQueues()
|
||||||
|
{
|
||||||
|
for(auto worker : workers)
|
||||||
|
{
|
||||||
|
delete worker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JobQueue::runJobs(FiberJob* jobs, uint32 numJobs)
|
||||||
|
{
|
||||||
|
for(uint32 i = 0; i < numJobs; ++i)
|
||||||
|
{
|
||||||
|
JobPriorityInfo& info = priorityQueues[(size_t)jobs[i].getPriority()];
|
||||||
|
std::unique_lock lock(info.jobQueueLock);
|
||||||
|
info.jobQueue.add(std::move(jobs[i]));
|
||||||
|
//info.jobQueueCV.notify_one();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JobQueue::waitForCounter(PCounter counter, uint32 waitFor)
|
||||||
|
{
|
||||||
|
while(counter->lessThan(waitFor))
|
||||||
|
std::this_thread::yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
void JobQueue::suspendJob(FiberTask&& task)
|
||||||
|
{
|
||||||
|
JobPriorityInfo& info = priorityQueues[(size_t)task.getPriority()];
|
||||||
|
std::unique_lock lock(info.jobQueueLock);
|
||||||
|
info.waiterQueue[task.getCounter()].add(task);
|
||||||
|
}
|
||||||
|
void JobQueue::refreshWaiterQueue()
|
||||||
|
{
|
||||||
|
JobPriorityInfo& info = priorityQueues[(size_t)priority];
|
||||||
|
//shortcut to avoid iterator creation
|
||||||
|
if(info.waiterQueue.empty())
|
||||||
|
return;
|
||||||
|
for(auto it : info.waiterQueue)
|
||||||
|
{
|
||||||
|
auto& entries = info.waiterQueue[it.key];
|
||||||
|
for(uint32 i = 0; i < entries.size(); ++i)
|
||||||
|
{
|
||||||
|
if(it.key->greaterEqual(entries[i].getTarget()))
|
||||||
|
{
|
||||||
|
info.resumableTasks.add(std::move(entries[i]));
|
||||||
|
entries.remove(i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JobQueue::work()
|
||||||
|
{
|
||||||
|
JobPriorityInfo& targetInfo = priorityQueues[(size_t)priority];
|
||||||
|
auto& jobQueue = targetInfo.jobQueue;
|
||||||
|
auto& resumableTasks = targetInfo.resumableTasks;
|
||||||
|
while(running)
|
||||||
|
{
|
||||||
|
std::unique_lock lock(targetInfo.jobQueueLock);
|
||||||
|
refreshWaiterQueue();
|
||||||
|
if(resumableTasks.size() > 0)
|
||||||
|
{
|
||||||
|
FiberTask task = std::move(resumableTasks.front());
|
||||||
|
resumableTasks.popFront();
|
||||||
|
lock.unlock();
|
||||||
|
task.resume();
|
||||||
|
lock.lock();
|
||||||
|
}
|
||||||
|
if(jobQueue.size() > 0)
|
||||||
|
{
|
||||||
|
FiberJob job = std::move(jobQueue.front());
|
||||||
|
jobQueue.popFront();
|
||||||
|
lock.unlock();
|
||||||
|
job();
|
||||||
|
lock.lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "MinimalEngine.h"
|
||||||
|
#include "Containers/List.h"
|
||||||
|
#include <coroutine>
|
||||||
|
namespace Seele
|
||||||
|
{
|
||||||
|
namespace Fibers
|
||||||
|
{
|
||||||
|
class FiberJob;
|
||||||
|
DECLARE_REF(Counter);
|
||||||
|
enum class JobPriority : size_t
|
||||||
|
{
|
||||||
|
HIGH = 0,
|
||||||
|
MEDIUM,
|
||||||
|
LOW,
|
||||||
|
IO,
|
||||||
|
NUM_PRIORITIES
|
||||||
|
};
|
||||||
|
struct AtomicJobQueue
|
||||||
|
{
|
||||||
|
};
|
||||||
|
class FiberTask;
|
||||||
|
struct JobPriorityInfo
|
||||||
|
{
|
||||||
|
List<FiberJob> jobQueue;
|
||||||
|
Map<PCounter, Array<FiberTask>> waiterQueue;
|
||||||
|
List<FiberTask> resumableTasks;
|
||||||
|
std::mutex jobQueueLock;
|
||||||
|
};
|
||||||
|
class JobQueue
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
JobQueue(JobPriority priority);
|
||||||
|
JobQueue(const JobQueue& other) = delete;
|
||||||
|
JobQueue(JobQueue&& other) = delete;
|
||||||
|
JobQueue& operator=(const JobQueue& other) = delete;
|
||||||
|
JobQueue& operator=(JobQueue&& other) = delete;
|
||||||
|
~JobQueue();
|
||||||
|
static void initJobQueues();
|
||||||
|
static void cleanupJobQueues();
|
||||||
|
static void runJobs(FiberJob* jobs, uint32 numJobs);
|
||||||
|
//This does in fact not do any coroutine stuff, but is a simple busy wait
|
||||||
|
//For coroutine waits, you have to be in a coroutine, and
|
||||||
|
static void waitForCounter(PCounter counter, uint32 waitFor);
|
||||||
|
static void suspendJob(FiberTask&& task);
|
||||||
|
void refreshWaiterQueue();
|
||||||
|
private:
|
||||||
|
void work();
|
||||||
|
static Array<JobQueue*> workers;
|
||||||
|
static StaticArray<JobPriorityInfo, (size_t)JobPriority::NUM_PRIORITIES> priorityQueues;
|
||||||
|
std::thread threadHandle;
|
||||||
|
JobPriority priority;
|
||||||
|
bool running = true;
|
||||||
|
};
|
||||||
|
} // namespace Fibers
|
||||||
|
} // namespace Seele
|
||||||
@@ -57,7 +57,7 @@ private:
|
|||||||
template<class Archive>
|
template<class Archive>
|
||||||
void serialize(Archive& ar, const unsigned int version)
|
void serialize(Archive& ar, const unsigned int version)
|
||||||
{
|
{
|
||||||
ar & referencedMaterial->getFullPath();
|
//ar & referencedMaterial->getFullPath();
|
||||||
//TODO:
|
//TODO:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ Gfx::VertexElement VertexShaderInput::accessStreamComponent(const VertexStreamCo
|
|||||||
vertexStream.stride = component.stride;
|
vertexStream.stride = component.stride;
|
||||||
vertexStream.offset = component.offset;
|
vertexStream.offset = component.offset;
|
||||||
|
|
||||||
return Gfx::VertexElement(streams.indexOf(streams.addUnique(vertexStream)), component.offset, component.type, attributeIndex, vertexStream.stride);
|
return Gfx::VertexElement((uint8)streams.indexOf(streams.addUnique(vertexStream)), component.offset, component.type, attributeIndex, vertexStream.stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::VertexElement VertexShaderInput::accessPositionStreamComponent(const VertexStreamComponent& component, uint8 attributeIndex)
|
Gfx::VertexElement VertexShaderInput::accessPositionStreamComponent(const VertexStreamComponent& component, uint8 attributeIndex)
|
||||||
@@ -101,7 +101,7 @@ Gfx::VertexElement VertexShaderInput::accessPositionStreamComponent(const Vertex
|
|||||||
vertexStream.stride = component.stride;
|
vertexStream.stride = component.stride;
|
||||||
vertexStream.offset = component.offset;
|
vertexStream.offset = component.offset;
|
||||||
|
|
||||||
return Gfx::VertexElement(streams.indexOf(streams.addUnique(vertexStream)), component.offset, component.type, attributeIndex, vertexStream.stride);
|
return Gfx::VertexElement((uint8)streams.indexOf(streams.addUnique(vertexStream)), component.offset, component.type, attributeIndex, vertexStream.stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexShaderInput::initDeclaration(Gfx::PGraphics graphics, Array<Gfx::VertexElement>& elements)
|
void VertexShaderInput::initDeclaration(Gfx::PGraphics graphics, Array<Gfx::VertexElement>& elements)
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ void CmdBuffer::beginRenderPass(PRenderPass newRenderPass, PFramebuffer newFrame
|
|||||||
|
|
||||||
VkRenderPassBeginInfo beginInfo =
|
VkRenderPassBeginInfo beginInfo =
|
||||||
init::RenderPassBeginInfo();
|
init::RenderPassBeginInfo();
|
||||||
beginInfo.clearValueCount = renderPass->getClearValueCount();
|
beginInfo.clearValueCount = (uint32)renderPass->getClearValueCount();
|
||||||
beginInfo.pClearValues = renderPass->getClearValues();
|
beginInfo.pClearValues = renderPass->getClearValues();
|
||||||
beginInfo.renderArea = renderPass->getRenderArea();
|
beginInfo.renderArea = renderPass->getRenderArea();
|
||||||
beginInfo.renderPass = renderPass->getHandle();
|
beginInfo.renderPass = renderPass->getHandle();
|
||||||
@@ -95,7 +95,7 @@ void CmdBuffer::executeCommands(Array<Gfx::PRenderCommand> commands)
|
|||||||
}
|
}
|
||||||
cmdBuffers[i] = command->getHandle();
|
cmdBuffers[i] = command->getHandle();
|
||||||
}
|
}
|
||||||
vkCmdExecuteCommands(handle, cmdBuffers.size(), cmdBuffers.data());
|
vkCmdExecuteCommands(handle, (uint32)cmdBuffers.size(), cmdBuffers.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmdBuffer::addWaitSemaphore(VkPipelineStageFlags flags, PSemaphore semaphore)
|
void CmdBuffer::addWaitSemaphore(VkPipelineStageFlags flags, PSemaphore semaphore)
|
||||||
@@ -212,7 +212,7 @@ void SecondaryCmdBuffer::bindDescriptor(const Array<Gfx::PDescriptorSet>& descri
|
|||||||
boundDescriptors.add(descriptorSet);
|
boundDescriptors.add(descriptorSet);
|
||||||
sets[descriptorSet->getSetIndex()] = descriptorSet->getHandle();
|
sets[descriptorSet->getSetIndex()] = descriptorSet->getHandle();
|
||||||
}
|
}
|
||||||
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), 0, descriptorSets.size(), sets, 0, nullptr);
|
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets, 0, nullptr);
|
||||||
delete[] sets;
|
delete[] sets;
|
||||||
}
|
}
|
||||||
void SecondaryCmdBuffer::bindVertexBuffer(const Array<VertexInputStream>& streams)
|
void SecondaryCmdBuffer::bindVertexBuffer(const Array<VertexInputStream>& streams)
|
||||||
@@ -225,7 +225,7 @@ void SecondaryCmdBuffer::bindVertexBuffer(const Array<VertexInputStream>& stream
|
|||||||
buffers[i] = buf->getHandle();
|
buffers[i] = buf->getHandle();
|
||||||
offsets[i] = streams[i].offset;
|
offsets[i] = streams[i].offset;
|
||||||
};
|
};
|
||||||
vkCmdBindVertexBuffers(handle, 0, streams.size(), buffers.data(), offsets.data());
|
vkCmdBindVertexBuffers(handle, 0, (uint32)streams.size(), buffers.data(), offsets.data());
|
||||||
}
|
}
|
||||||
void SecondaryCmdBuffer::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer)
|
void SecondaryCmdBuffer::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ void DescriptorLayout::create()
|
|||||||
binding.pImmutableSamplers = nullptr;
|
binding.pImmutableSamplers = nullptr;
|
||||||
}
|
}
|
||||||
VkDescriptorSetLayoutCreateInfo createInfo =
|
VkDescriptorSetLayoutCreateInfo createInfo =
|
||||||
init::DescriptorSetLayoutCreateInfo(bindings.data(), bindings.size());
|
init::DescriptorSetLayoutCreateInfo(bindings.data(), (uint32)bindings.size());
|
||||||
VK_CHECK(vkCreateDescriptorSetLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
|
VK_CHECK(vkCreateDescriptorSetLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
|
||||||
|
|
||||||
allocator = new DescriptorAllocator(graphics, *this);
|
allocator = new DescriptorAllocator(graphics, *this);
|
||||||
@@ -75,7 +75,7 @@ void PipelineLayout::create()
|
|||||||
}
|
}
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo createInfo =
|
VkPipelineLayoutCreateInfo createInfo =
|
||||||
init::PipelineLayoutCreateInfo(vulkanDescriptorLayouts.data(), vulkanDescriptorLayouts.size());
|
init::PipelineLayoutCreateInfo(vulkanDescriptorLayouts.data(), (uint32)vulkanDescriptorLayouts.size());
|
||||||
Array<VkPushConstantRange> vkPushConstants(pushConstants.size());
|
Array<VkPushConstantRange> vkPushConstants(pushConstants.size());
|
||||||
for (size_t i = 0; i < pushConstants.size(); i++)
|
for (size_t i = 0; i < pushConstants.size(); i++)
|
||||||
{
|
{
|
||||||
@@ -83,7 +83,7 @@ void PipelineLayout::create()
|
|||||||
vkPushConstants[i].size = pushConstants[i].size;
|
vkPushConstants[i].size = pushConstants[i].size;
|
||||||
vkPushConstants[i].stageFlags = cast((VkShaderStageFlagBits)pushConstants[i].stageFlags);
|
vkPushConstants[i].stageFlags = cast((VkShaderStageFlagBits)pushConstants[i].stageFlags);
|
||||||
}
|
}
|
||||||
createInfo.pushConstantRangeCount = vkPushConstants.size();
|
createInfo.pushConstantRangeCount = (uint32)vkPushConstants.size();
|
||||||
createInfo.pPushConstantRanges = vkPushConstants.data();
|
createInfo.pPushConstantRanges = vkPushConstants.data();
|
||||||
|
|
||||||
boost::crc_32_type result;
|
boost::crc_32_type result;
|
||||||
@@ -198,7 +198,7 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
|
|||||||
bool DescriptorSet::operator<(Gfx::PDescriptorSet other)
|
bool DescriptorSet::operator<(Gfx::PDescriptorSet other)
|
||||||
{
|
{
|
||||||
PDescriptorSet otherSet = other.cast<DescriptorSet>();
|
PDescriptorSet otherSet = other.cast<DescriptorSet>();
|
||||||
return setHandle < otherSet->setHandle;
|
return this < otherSet.getHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::writeChanges()
|
void DescriptorSet::writeChanges()
|
||||||
@@ -210,7 +210,7 @@ void DescriptorSet::writeChanges()
|
|||||||
currentlyBound->getManager()->waitForCommands(currentlyBound);
|
currentlyBound->getManager()->waitForCommands(currentlyBound);
|
||||||
currentlyBound = nullptr;
|
currentlyBound = nullptr;
|
||||||
}
|
}
|
||||||
vkUpdateDescriptorSets(graphics->getDevice(), writeDescriptors.size(), writeDescriptors.data(), 0, nullptr);
|
vkUpdateDescriptorSets(graphics->getDevice(), (uint32)writeDescriptors.size(), writeDescriptors.data(), 0, nullptr);
|
||||||
writeDescriptors.clear();
|
writeDescriptors.clear();
|
||||||
imageInfos.clear();
|
imageInfos.clear();
|
||||||
bufferInfos.clear();
|
bufferInfos.clear();
|
||||||
@@ -241,7 +241,7 @@ DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout &l
|
|||||||
poolSizes.add(size);
|
poolSizes.add(size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
VkDescriptorPoolCreateInfo createInfo = init::DescriptorPoolCreateInfo(poolSizes.size(), poolSizes.data(), maxSets);
|
VkDescriptorPoolCreateInfo createInfo = init::DescriptorPoolCreateInfo((uint32)poolSizes.size(), poolSizes.data(), maxSets);
|
||||||
VK_CHECK(vkCreateDescriptorPool(graphics->getDevice(), &createInfo, nullptr, &poolHandle));
|
VK_CHECK(vkCreateDescriptorPool(graphics->getDevice(), &createInfo, nullptr, &poolHandle));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::PRende
|
|||||||
VkFramebufferCreateInfo createInfo =
|
VkFramebufferCreateInfo createInfo =
|
||||||
init::FramebufferCreateInfo(
|
init::FramebufferCreateInfo(
|
||||||
renderPass->getHandle(),
|
renderPass->getHandle(),
|
||||||
attachments.size(),
|
(uint32)attachments.size(),
|
||||||
attachments.data(),
|
attachments.data(),
|
||||||
renderPass->getRenderArea().extent.width,
|
renderPass->getRenderArea().extent.width,
|
||||||
renderPass->getRenderArea().extent.height,
|
renderPass->getRenderArea().extent.height,
|
||||||
|
|||||||
@@ -215,9 +215,9 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
|
|||||||
std::memcpy(hashStruct.attribs, attributes.data(), attributes.size() * sizeof(VkVertexInputAttributeDescription));
|
std::memcpy(hashStruct.attribs, attributes.data(), attributes.size() * sizeof(VkVertexInputAttributeDescription));
|
||||||
|
|
||||||
vertexInput.pVertexBindingDescriptions = bindings.data();
|
vertexInput.pVertexBindingDescriptions = bindings.data();
|
||||||
vertexInput.vertexBindingDescriptionCount = bindings.size();
|
vertexInput.vertexBindingDescriptionCount = (uint32)bindings.size();
|
||||||
vertexInput.pVertexAttributeDescriptions = attributes.data();
|
vertexInput.pVertexAttributeDescriptions = attributes.data();
|
||||||
vertexInput.vertexAttributeDescriptionCount = attributes.size();
|
vertexInput.vertexAttributeDescriptionCount = (uint32)attributes.size();
|
||||||
|
|
||||||
VkPipelineInputAssemblyStateCreateInfo assemblyInfo =
|
VkPipelineInputAssemblyStateCreateInfo assemblyInfo =
|
||||||
init::PipelineInputAssemblyStateCreateInfo(
|
init::PipelineInputAssemblyStateCreateInfo(
|
||||||
@@ -291,7 +291,7 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
|
|||||||
}
|
}
|
||||||
VkPipelineColorBlendStateCreateInfo blendState =
|
VkPipelineColorBlendStateCreateInfo blendState =
|
||||||
init::PipelineColorBlendStateCreateInfo(
|
init::PipelineColorBlendStateCreateInfo(
|
||||||
blendAttachments.size(),
|
(uint32)blendAttachments.size(),
|
||||||
blendAttachments.data()
|
blendAttachments.data()
|
||||||
);
|
);
|
||||||
blendState.logicOpEnable = gfxInfo.colorBlend.logicOpEnable;
|
blendState.logicOpEnable = gfxInfo.colorBlend.logicOpEnable;
|
||||||
|
|||||||
@@ -91,10 +91,10 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::PRenderTargetLayout layout)
|
|||||||
VkSubpassDescription subPassDesc =
|
VkSubpassDescription subPassDesc =
|
||||||
init::SubpassDescription(
|
init::SubpassDescription(
|
||||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
colorRefs.size(),
|
(uint32)colorRefs.size(),
|
||||||
colorRefs.data(),
|
colorRefs.data(),
|
||||||
&depthRef,
|
&depthRef,
|
||||||
inputRefs.size(),
|
(uint32)inputRefs.size(),
|
||||||
inputRefs.data());
|
inputRefs.data());
|
||||||
VkSubpassDependency dependency = {};
|
VkSubpassDependency dependency = {};
|
||||||
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||||
@@ -108,7 +108,7 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::PRenderTargetLayout layout)
|
|||||||
|
|
||||||
VkRenderPassCreateInfo info =
|
VkRenderPassCreateInfo info =
|
||||||
init::RenderPassCreateInfo(
|
init::RenderPassCreateInfo(
|
||||||
attachments.size(),
|
(uint32)attachments.size(),
|
||||||
attachments.data(),
|
attachments.data(),
|
||||||
1,
|
1,
|
||||||
&subPassDesc,
|
&subPassDesc,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public:
|
|||||||
{
|
{
|
||||||
return renderPass;
|
return renderPass;
|
||||||
}
|
}
|
||||||
inline uint32 getClearValueCount() const
|
inline size_t getClearValueCount() const
|
||||||
{
|
{
|
||||||
return clearValues.size();
|
return clearValues.size();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ void Shader::create(const ShaderCreateInfo& createInfo)
|
|||||||
spAddSearchPath(request, "shaders/lib/");
|
spAddSearchPath(request, "shaders/lib/");
|
||||||
spAddSearchPath(request, "shaders/generated/");
|
spAddSearchPath(request, "shaders/generated/");
|
||||||
|
|
||||||
spSetGlobalGenericArgs(request, createInfo.typeParameter.size(), createInfo.typeParameter.data());
|
spSetGlobalGenericArgs(request, (int)createInfo.typeParameter.size(), createInfo.typeParameter.data());
|
||||||
|
|
||||||
int entryPointIndex = spAddEntryPoint(request, translationUnitIndex, entryPointName.c_str(), getStageFromShaderType(type));
|
int entryPointIndex = spAddEntryPoint(request, translationUnitIndex, entryPointName.c_str(), getStageFromShaderType(type));
|
||||||
if(spCompile(request))
|
if(spCompile(request))
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ void Material::compile()
|
|||||||
for(auto param : j["params"].items())
|
for(auto param : j["params"].items())
|
||||||
{
|
{
|
||||||
std::string type = param.value()["type"].get<std::string>();
|
std::string type = param.value()["type"].get<std::string>();
|
||||||
auto default = param.value().find("default");
|
auto defaultValue = param.value().find("default");
|
||||||
if(type.compare("float") == 0)
|
if(type.compare("float") == 0)
|
||||||
{
|
{
|
||||||
PFloatParameter p = new FloatParameter(param.key(), uniformBufferOffset, 0);
|
PFloatParameter p = new FloatParameter(param.key(), uniformBufferOffset, 0);
|
||||||
@@ -76,9 +76,9 @@ void Material::compile()
|
|||||||
uniformBinding = bindingCounter++;
|
uniformBinding = bindingCounter++;
|
||||||
}
|
}
|
||||||
uniformBufferOffset += 4;
|
uniformBufferOffset += 4;
|
||||||
if(default != param.value().end())
|
if(defaultValue != param.value().end())
|
||||||
{
|
{
|
||||||
p->data = std::stof(default.value().get<std::string>());
|
p->data = std::stof(defaultValue.value().get<std::string>());
|
||||||
}
|
}
|
||||||
parameters.add(p);
|
parameters.add(p);
|
||||||
}
|
}
|
||||||
@@ -92,9 +92,9 @@ void Material::compile()
|
|||||||
uniformBinding = bindingCounter++;
|
uniformBinding = bindingCounter++;
|
||||||
}
|
}
|
||||||
uniformBufferOffset += 12;
|
uniformBufferOffset += 12;
|
||||||
if(default != param.value().end())
|
if(defaultValue != param.value().end())
|
||||||
{
|
{
|
||||||
p->data = parseVector(default.value().get<std::string>().c_str());
|
p->data = parseVector(defaultValue.value().get<std::string>().c_str());
|
||||||
}
|
}
|
||||||
parameters.add(p);
|
parameters.add(p);
|
||||||
}
|
}
|
||||||
@@ -102,9 +102,9 @@ void Material::compile()
|
|||||||
{
|
{
|
||||||
PTextureParameter p = new TextureParameter(param.key(), 0, bindingCounter);
|
PTextureParameter p = new TextureParameter(param.key(), 0, bindingCounter);
|
||||||
layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
|
layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
|
||||||
if(default != param.value().end())
|
if(defaultValue != param.value().end())
|
||||||
{
|
{
|
||||||
p->data = AssetRegistry::findTexture(default.value().get<std::string>());
|
p->data = AssetRegistry::findTexture(defaultValue.value().get<std::string>());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public:
|
|||||||
Transform();
|
Transform();
|
||||||
Transform(const Transform &other);
|
Transform(const Transform &other);
|
||||||
Transform(Transform &&other);
|
Transform(Transform &&other);
|
||||||
Transform(Vector position);
|
explicit Transform(Vector position);
|
||||||
Transform(Vector position, Quaternion rotation);
|
Transform(Vector position, Quaternion rotation);
|
||||||
Transform(Vector position, Quaternion rotation, Vector scale);
|
Transform(Vector position, Quaternion rotation, Vector scale);
|
||||||
Transform(Quaternion rotation, Vector scale);
|
Transform(Quaternion rotation, Vector scale);
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
T *handle;
|
T *handle;
|
||||||
uint64 refCount;
|
std::atomic_uint64_t refCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ Scene::Scene(Gfx::PGraphics graphics)
|
|||||||
lightEnv.directionalLights[0].intensity = Vector4(1, 1, 1, 1);
|
lightEnv.directionalLights[0].intensity = Vector4(1, 1, 1, 1);
|
||||||
lightEnv.numDirectionalLights = 1;
|
lightEnv.numDirectionalLights = 1;
|
||||||
lightEnv.numPointLights = 0;
|
lightEnv.numPointLights = 0;
|
||||||
srand(time(NULL));
|
srand((unsigned int)time(NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene::~Scene()
|
Scene::~Scene()
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
#include "Graphics/RenderCore.h"
|
#include "Graphics/RenderCore.h"
|
||||||
#include "Window/SceneView.h"
|
#include "Window/SceneView.h"
|
||||||
#include "Asset/AssetRegistry.h"
|
#include "Asset/AssetRegistry.h"
|
||||||
|
#include "Fibers/Fibers.h"
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
RenderCore core;
|
RenderCore core;
|
||||||
|
|||||||
@@ -5,5 +5,6 @@ target_sources(Seele_unit_tests
|
|||||||
EngineTest.cpp)
|
EngineTest.cpp)
|
||||||
target_include_directories(Seele_unit_tests PUBLIC ./)
|
target_include_directories(Seele_unit_tests PUBLIC ./)
|
||||||
add_subdirectory(Containers/)
|
add_subdirectory(Containers/)
|
||||||
|
add_subdirectory(Fibers/)
|
||||||
add_subdirectory(Graphics/)
|
add_subdirectory(Graphics/)
|
||||||
add_subdirectory(Math/)
|
add_subdirectory(Math/)
|
||||||
@@ -31,7 +31,7 @@ BOOST_AUTO_TEST_CASE(for_each)
|
|||||||
map[6] = 4;
|
map[6] = 4;
|
||||||
map[4] = 7;
|
map[4] = 7;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for(auto it = map.begin(); it != map.end(); ++it)
|
for(auto it : map)
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
BOOST_TEST_GLOBAL_FIXTURE(GlobalFixture);
|
||||||
BOOST_AUTO_TEST_SUITE(RefPtr)
|
BOOST_AUTO_TEST_SUITE(RefPtr)
|
||||||
|
|
||||||
struct TestStruct
|
struct TestStruct
|
||||||
|
|||||||
@@ -1 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "Fibers/JobQueue.h"
|
||||||
|
|
||||||
|
namespace Seele
|
||||||
|
{
|
||||||
|
struct GlobalFixture
|
||||||
|
{
|
||||||
|
GlobalFixture()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
~GlobalFixture()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Fibers::JobQueue::initJobQueues();
|
||||||
|
}
|
||||||
|
void teardown()
|
||||||
|
{
|
||||||
|
Fibers::JobQueue::cleanupJobQueues();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
target_sources(Seele_unit_tests
|
||||||
|
PRIVATE
|
||||||
|
../../../src/Engine/Fibers/JobQueue.cpp
|
||||||
|
../../../src/Engine/Fibers/Fibers.cpp
|
||||||
|
Fibers.cpp)
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#include "EngineTest.h"
|
||||||
|
#include "MinimalEngine.h"
|
||||||
|
#include "Fibers/Fibers.h"
|
||||||
|
#include <coroutine>
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
using namespace Seele;
|
||||||
|
using namespace Seele::Fibers;
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE(Fibers_Suite)
|
||||||
|
|
||||||
|
FiberTask basicFiberSync1(PCounter syncCounter)
|
||||||
|
{
|
||||||
|
syncCounter->increment();
|
||||||
|
std::cout << "basicFiberSync1 start" << std::endl;
|
||||||
|
co_await AwaitCounter{syncCounter, 2};
|
||||||
|
std::cout << "basicFiberSync1 has resumed, counter is " << syncCounter << std::endl;
|
||||||
|
co_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FiberTask basicFiberSync2(PCounter syncCounter)
|
||||||
|
{
|
||||||
|
syncCounter->increment();
|
||||||
|
std::cout << "basicFiberSync2 start" << std::endl;
|
||||||
|
co_await AwaitCounter(syncCounter, 3);
|
||||||
|
std::cout << "basicFiberSync2 has resumed, counter is " << syncCounter << std::endl;
|
||||||
|
co_return;
|
||||||
|
}
|
||||||
|
BOOST_AUTO_TEST_CASE(basicFiberSync)
|
||||||
|
{
|
||||||
|
PCounter syncCounter = new Counter(1);
|
||||||
|
PCounter counter1 = new Counter();
|
||||||
|
FiberJob job1 = FiberJob(counter1, &basicFiberSync1, syncCounter);
|
||||||
|
JobQueue::runJobs(&job1, 1);
|
||||||
|
FiberJob job2 = FiberJob(counter1, &basicFiberSync2, syncCounter);
|
||||||
|
JobQueue::runJobs(&job2, 1);
|
||||||
|
while(counter1->lessThan(2))
|
||||||
|
std::this_thread::yield();
|
||||||
|
BOOST_CHECK_EQUAL(syncCounter->getValue(), 3);
|
||||||
|
}
|
||||||
|
FiberTask incrementJob(PCounter localCounter)
|
||||||
|
{
|
||||||
|
localCounter->increment();
|
||||||
|
co_return;
|
||||||
|
}
|
||||||
|
BOOST_AUTO_TEST_CASE(jobBatch)
|
||||||
|
{
|
||||||
|
PCounter localCounter = new Counter();
|
||||||
|
PCounter jobCounter = new Counter();
|
||||||
|
FiberJob jobs[256];
|
||||||
|
for(int i = 0; i < 256; ++i)
|
||||||
|
{
|
||||||
|
jobs[i] = FiberJob(jobCounter, JobPriority::HIGH, &incrementJob, localCounter);
|
||||||
|
}
|
||||||
|
JobQueue::runJobs(jobs, 256);
|
||||||
|
while(jobCounter->lessThan(256))
|
||||||
|
std::this_thread::yield();
|
||||||
|
BOOST_CHECK_EQUAL(localCounter->getValue(), 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
Reference in New Issue
Block a user