Provisional multithreading framework

This commit is contained in:
Dynamitos
2021-03-31 12:18:16 +02:00
parent fb3c66cc4c
commit 28f0f88c03
37 changed files with 788 additions and 186 deletions
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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"
} }
} }
} }
+2 -1
View File
@@ -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
View File
@@ -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--------------------
+1
View File
@@ -0,0 +1 @@
This file needs to be here because otherwise git will delete the folder and the engine can't automatically generate it
+1
View File
@@ -0,0 +1 @@
add_subdirectory(x64/)
+4 -5
View File
@@ -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);
+2
View File
@@ -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/)
+126 -100
View File
@@ -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
+8
View File
@@ -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++;
+56 -26
View File
@@ -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,8 +261,7 @@ 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);
if (root == nullptr || root->pair.key < key || key < root->pair.key) if (root == nullptr || root->pair.key < key || key < root->pair.key)
@@ -268,7 +272,18 @@ public:
} }
return root->pair.value; return root->pair.value;
} }
Iterator find(const K &key) 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)
{ {
root = splay(root, key); root = splay(root, key);
if (root == nullptr || root->pair.key != key) if (root == nullptr || root->pair.key != key)
@@ -277,10 +292,25 @@ public:
} }
return Iterator(root); return Iterator(root);
} }
Iterator erase(const K &key) 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)
{ {
root = remove(root, key); root = remove(root, key);
refreshIterators(); refreshIterators();
return Iterator(root);
}
Iterator erase(K&& key)
{
root = remove(root, std::move(key));
refreshIterators();
return Iterator(root); return Iterator(root);
} }
void clear() void clear()
@@ -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))
{ {
+6
View File
@@ -0,0 +1,6 @@
target_sources(SeeleEngine
PRIVATE
Fibers.h
Fibers.cpp
JobQueue.h
JobQueue.cpp)
+36
View File
@@ -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()
{
}
+205
View File
@@ -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
+134
View File
@@ -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();
}
}
}
+56
View File
@@ -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
+1 -1
View File
@@ -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:
} }
}; };
+2 -2
View File
@@ -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();
} }
+1 -1
View File
@@ -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))
+7 -7
View File
@@ -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
{ {
+1 -1
View File
@@ -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);
+1 -1
View File
@@ -108,7 +108,7 @@ public:
private: private:
T *handle; T *handle;
uint64 refCount; std::atomic_uint64_t refCount;
}; };
template <typename T> template <typename T>
+1 -1
View File
@@ -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()
+4
View File
@@ -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;
+1
View File
@@ -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/)
+1 -1
View File
@@ -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++;
} }
+1 -1
View File
@@ -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
+23 -1
View File
@@ -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();
}
};
};
+5
View File
@@ -0,0 +1,5 @@
target_sources(Seele_unit_tests
PRIVATE
../../../src/Engine/Fibers/JobQueue.cpp
../../../src/Engine/Fibers/Fibers.cpp
Fibers.cpp)
+61
View File
@@ -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()