3700 FPS here we go

This commit is contained in:
Dynamitos
2021-04-13 23:09:16 +02:00
parent d5f0fe644f
commit 312ae2af9a
36 changed files with 401 additions and 231 deletions
+1 -1
View File
@@ -11,7 +11,7 @@
"UNICODE", "UNICODE",
"_UNICODE" "_UNICODE"
], ],
"intelliSenseMode": "clang-x64", "intelliSenseMode": "msvc-x64",
"configurationProvider": "ms-vscode.cmake-tools", "configurationProvider": "ms-vscode.cmake-tools",
"cppStandard": "c++20", "cppStandard": "c++20",
"browse": { "browse": {
+20 -1
View File
@@ -5,7 +5,7 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "Engine", "name": "Engine Debug",
"type": "cppvsdbg", "type": "cppvsdbg",
"request": "launch", "request": "launch",
"program": "${workspaceRoot}/bin/Debug/SeeleEngine.exe", "program": "${workspaceRoot}/bin/Debug/SeeleEngine.exe",
@@ -23,6 +23,25 @@
"traceResponse": true "traceResponse": true
} }
}, },
{
"name": "Engine Release",
"type": "cppvsdbg",
"request": "launch",
"program": "${workspaceRoot}/bin/Release/SeeleEngine.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceRoot}/bin/Release",
"console": "internalConsole",
"environment": [],
"symbolSearchPath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.25.28610\\lib\\x64",
"requireExactSource": false,
"logging": {
"moduleLoad": false,
"exceptions": true,
"trace": true,
"traceResponse": true
}
},
{ {
"name": "Test", "name": "Test",
"type": "cppvsdbg", "type": "cppvsdbg",
+3 -2
View File
@@ -106,12 +106,13 @@
"scoped_allocator": "cpp", "scoped_allocator": "cpp",
"stack": "cpp", "stack": "cpp",
"coroutine": "cpp", "coroutine": "cpp",
"*.tcc": "cpp" "*.tcc": "cpp",
"stop_token": "cpp"
}, },
"cmake.skipConfigureIfCachePresent": false, "cmake.skipConfigureIfCachePresent": false,
"cmake.configureArgs": [ "cmake.configureArgs": [
"-Wno-dev" "-Wno-dev"
], ],
"C_Cpp.default.cppStandard": "c++20", "C_Cpp.default.cppStandard": "c++20",
"C_Cpp.default.intelliSenseMode": "gcc-x64" "C_Cpp.default.intelliSenseMode": "msvc-x64"
} }
-1
View File
@@ -16,7 +16,6 @@ set(GLFW_ROOT ${EXTERNAL_ROOT}/glfw)
set(JSON_ROOT ${EXTERNAL_ROOT}/json) set(JSON_ROOT ${EXTERNAL_ROOT}/json)
set(STB_ROOT ${EXTERNAL_ROOT}/stb) set(STB_ROOT ${EXTERNAL_ROOT}/stb)
set(SPIRV_ROOT ${EXTERNAL_ROOT}/SPIRV-Cross) set(SPIRV_ROOT ${EXTERNAL_ROOT}/SPIRV-Cross)
set(Boost_DEBUG ON)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/)
+2
View File
@@ -6,6 +6,7 @@
"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" "CMAKE_BUILD_TYPE": "Debug"
@@ -14,6 +15,7 @@
"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" "CMAKE_BUILD_TYPE": "Release"
+2 -1
View File
@@ -30,7 +30,8 @@ if (WIN32)
PATHS PATHS
$ENV{PROGRAMFILES}/lib $ENV{PROGRAMFILES}/lib
${ASSIMP_ROOT}/lib ${ASSIMP_ROOT}/lib
${ASSIMP_ROOT}/lib/${CMAKE_BUILD_TYPE}) ${ASSIMP_ROOT}/code
PATH_SUFFIXES Debug Release)
find_file( find_file(
ASSIMP_BINARY ASSIMP_BINARY
+5 -2
View File
@@ -14,8 +14,11 @@ set(BUILD_SHARED_LIBS ON CACHE INTERNAL "")
add_subdirectory(${ASSIMP_ROOT} ${ASSIMP_ROOT}) add_subdirectory(${ASSIMP_ROOT} ${ASSIMP_ROOT})
target_compile_definitions(assimp PRIVATE _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING) target_compile_definitions(assimp PRIVATE _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING)
target_compile_options(assimp PRIVATE -Wno-error) #if(WIN32)
# target_compile_options(assimp PRIVATE /WX-)
#else()
# target_compile_options(assimp PRIVATE -Wno-error)
#endif()
#-------------BOOST---------------- #-------------BOOST----------------
list(APPEND DEPENDENCIES boost) list(APPEND DEPENDENCIES boost)
if(WIN32) if(WIN32)
+17 -2
View File
@@ -28,16 +28,31 @@ public:
std::string getExtension() const; std::string getExtension() const;
inline Status getStatus() inline Status getStatus()
{ {
std::scoped_lock lck(lock); std::unique_lock lck(lock);
return status; return status;
} }
inline void setStatus(Status status) inline void setStatus(Status status)
{ {
std::scoped_lock lck(lock); std::unique_lock lck(lock);
this->status = status; this->status = status;
if(status == Status::Ready)
{
readyCV.notify_all();
}
} }
protected: protected:
inline void waitReady()
{
std::unique_lock lck(lock);
if(status != Status::Ready)
{
std::cout << "Asset " << name.generic_string() << " not ready yet, waiting" << std::endl;
readyCV.wait(lck);
std::cout << "Asset " << name.generic_string() << " now ready, continuing" << std::endl;
}
}
std::mutex lock; std::mutex lock;
std::condition_variable readyCV;
std::ifstream& getReadStream(); std::ifstream& getReadStream();
std::ofstream& getWriteStream(); std::ofstream& getWriteStream();
private: private:
+3 -1
View File
@@ -43,7 +43,9 @@ void AssetRegistry::importFile(const std::string &filePath)
PMeshAsset AssetRegistry::findMesh(const std::string &filePath) PMeshAsset AssetRegistry::findMesh(const std::string &filePath)
{ {
return get().meshes[filePath]; auto it = get().meshes.find(filePath);
assert(it != get().meshes.end());
return it->value;
} }
PTextureAsset AssetRegistry::findTexture(const std::string &filePath) PTextureAsset AssetRegistry::findTexture(const std::string &filePath)
+3 -1
View File
@@ -1,5 +1,6 @@
#include "MeshAsset.h" #include "MeshAsset.h"
#include "Graphics/Mesh.h" #include "Graphics/Mesh.h"
#include "Graphics/VertexShaderInput.h"
#include <boost/archive/text_iarchive.hpp> #include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_oarchive.hpp>
@@ -40,7 +41,8 @@ void MeshAsset::addMesh(PMesh mesh)
referencedMaterials.add(mesh->referencedMaterial); referencedMaterials.add(mesh->referencedMaterial);
} }
const Array<PMesh> MeshAsset::getMeshes() const const Array<PMesh> MeshAsset::getMeshes()
{ {
waitReady();
return meshes; return meshes;
} }
+1 -1
View File
@@ -15,7 +15,7 @@ public:
virtual void save() override; virtual void save() override;
virtual void load() override; virtual void load() override;
void addMesh(PMesh mesh); void addMesh(PMesh mesh);
const Array<PMesh> getMeshes() const; const Array<PMesh> getMeshes();
private: private:
Array<PMesh> meshes; Array<PMesh> meshes;
Array<PMaterialAsset> referencedMaterials; Array<PMaterialAsset> referencedMaterials;
+9 -6
View File
@@ -29,7 +29,11 @@ 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)); std::filesystem::path assetPath = path.filename();
assetPath.replace_extension("asset");
PMeshAsset meshAsset = new MeshAsset(assetPath.generic_string());
AssetRegistry::get().registerMesh(meshAsset);
futures.add(std::async(std::launch::async, &MeshLoader::import, this, meshAsset, 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)
@@ -224,8 +228,9 @@ void MeshLoader::loadTextures(const aiScene* scene, const std::filesystem::path&
AssetRegistry::importFile(texPngPath.string()); AssetRegistry::importFile(texPngPath.string());
} }
} }
void MeshLoader::import(const std::filesystem::path &path) void MeshLoader::import(PMeshAsset meshAsset, const std::filesystem::path &path)
{ {
meshAsset->setStatus(Asset::Status::Loading);
Assimp::Importer importer; Assimp::Importer importer;
importer.ReadFile(path.string().c_str(), importer.ReadFile(path.string().c_str(),
aiProcess_FlipUVs | aiProcess_FlipUVs |
@@ -246,9 +251,7 @@ void MeshLoader::import(const std::filesystem::path &path)
List<aiNode *> meshNodes; List<aiNode *> meshNodes;
findMeshRoots(scene->mRootNode, meshNodes); findMeshRoots(scene->mRootNode, meshNodes);
std::filesystem::path filePath = path.filename();
filePath.replace_extension("asset");
PMeshAsset meshAsset = new MeshAsset(filePath.generic_string());
for (auto meshNode : meshNodes) for (auto meshNode : meshNodes)
{ {
for(uint32 i = 0; i < meshNode->mNumMeshes; ++i) for(uint32 i = 0; i < meshNode->mNumMeshes; ++i)
@@ -256,6 +259,6 @@ void MeshLoader::import(const std::filesystem::path &path)
meshAsset->addMesh(globalMeshes[meshNode->mMeshes[i]]); meshAsset->addMesh(globalMeshes[meshNode->mMeshes[i]]);
} }
} }
meshAsset->setStatus(Asset::Status::Ready);
meshAsset->save(); meshAsset->save();
AssetRegistry::get().registerMesh(meshAsset);
} }
+1 -1
View File
@@ -25,7 +25,7 @@ private:
void loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, const Array<PMaterialAsset>& materials, Gfx::PGraphics graphics); void loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, const Array<PMaterialAsset>& materials, Gfx::PGraphics graphics);
void convertAssimpARGB(unsigned char* dst, aiTexel* src, uint32 numPixels); void convertAssimpARGB(unsigned char* dst, aiTexel* src, uint32 numPixels);
void import(const std::filesystem::path& path); void import(PMeshAsset meshAsset, const std::filesystem::path& path);
List<std::future<void>> futures; List<std::future<void>> futures;
Gfx::PGraphics graphics; Gfx::PGraphics graphics;
}; };
+4 -2
View File
@@ -28,12 +28,14 @@ void TextureLoader::importAsset(const std::filesystem::path& filePath)
PTextureAsset asset = new TextureAsset(assetFileName.replace_extension("asset").filename().generic_string()); PTextureAsset asset = new TextureAsset(assetFileName.replace_extension("asset").filename().generic_string());
asset->setStatus(Asset::Status::Loading); asset->setStatus(Asset::Status::Loading);
asset->setTexture(placeholderTexture); asset->setTexture(placeholderTexture);
std::cout << "Loading texture, placeholder" << std::endl;
AssetRegistry::get().textures[asset->getFileName()] = asset; AssetRegistry::get().textures[asset->getFileName()] = asset;
//futures.add(std::async(std::launch::async, [this, filePath, asset] () mutable { futures.add(std::async(std::launch::async, [this, filePath, asset] () mutable {
Gfx::PTexture2D texture = import(filePath); Gfx::PTexture2D texture = import(filePath);
asset->setTexture(texture); asset->setTexture(texture);
asset->setStatus(Asset::Status::Ready); asset->setStatus(Asset::Status::Ready);
//})); std::cout << "Finished loading texture" << std::endl;
}));
} }
PTextureAsset TextureLoader::getPlaceholderTexture() PTextureAsset TextureLoader::getPlaceholderTexture()
+43 -28
View File
@@ -12,10 +12,14 @@
namespace Seele namespace Seele
{ {
enum class Init_t {
NO_INIT
};
template <typename T> template <typename T>
struct Array struct Array
{ {
public: public:
Array() Array()
: arraySize(0) : arraySize(0)
, allocated(DEFAULT_ALLOC_SIZE) , allocated(DEFAULT_ALLOC_SIZE)
@@ -23,7 +27,15 @@ namespace Seele
_data = new T[DEFAULT_ALLOC_SIZE]; _data = new T[DEFAULT_ALLOC_SIZE];
assert(_data != nullptr); assert(_data != nullptr);
//std::memset(_data, 0, sizeof(T) * DEFAULT_ALLOC_SIZE); //std::memset(_data, 0, sizeof(T) * DEFAULT_ALLOC_SIZE);
refreshIterators(); markIteratorDirty();
}
Array(Init_t)
: arraySize(0)
, allocated(0)
, _data(nullptr)
, beginIt(Iterator(nullptr))
, endIt(Iterator(nullptr))
{
} }
Array(size_t size, T value = T()) Array(size_t size, T value = T())
: arraySize(size) : arraySize(size)
@@ -36,7 +48,7 @@ namespace Seele
assert(i < size); assert(i < size);
_data[i] = value; _data[i] = value;
} }
refreshIterators(); markIteratorDirty();
} }
Array(std::initializer_list<T> init) Array(std::initializer_list<T> init)
: arraySize(init.size()) : arraySize(init.size())
@@ -49,7 +61,7 @@ namespace Seele
assert(i < init.size()); assert(i < init.size());
_data[i] = *it; _data[i] = *it;
} }
refreshIterators(); markIteratorDirty();
} }
Array(const Array &other) Array(const Array &other)
: arraySize(other.arraySize) : arraySize(other.arraySize)
@@ -57,7 +69,7 @@ namespace Seele
{ {
_data = new T[other.allocated]; _data = new T[other.allocated];
assert(_data != nullptr); assert(_data != nullptr);
refreshIterators(); markIteratorDirty();
std::copy(other.begin(), other.end(), beginIt); std::copy(other.begin(), other.end(), beginIt);
} }
Array(Array &&other) noexcept Array(Array &&other) noexcept
@@ -68,7 +80,7 @@ namespace Seele
other._data = nullptr; other._data = nullptr;
other.allocated = 0; other.allocated = 0;
other.arraySize = 0; other.arraySize = 0;
refreshIterators(); markIteratorDirty();
} }
Array &operator=(const Array &other) noexcept Array &operator=(const Array &other) noexcept
{ {
@@ -76,12 +88,15 @@ namespace Seele
{ {
if (_data != nullptr) if (_data != nullptr)
{ {
delete[] _data; if(other.arraySize > allocated)
{
delete[] _data;
_data = new T[other.allocated];
allocated = other.allocated;
}
} }
allocated = other.allocated;
arraySize = other.arraySize; arraySize = other.arraySize;
_data = new T[other.allocated]; markIteratorDirty();
refreshIterators();
std::copy(other.begin(), other.end(), beginIt); std::copy(other.begin(), other.end(), beginIt);
} }
return *this; return *this;
@@ -93,12 +108,13 @@ namespace Seele
if (_data != nullptr) if (_data != nullptr)
{ {
delete[] _data; delete[] _data;
_data = nullptr;
} }
allocated = std::move(other.allocated); allocated = std::move(other.allocated);
arraySize = std::move(other.arraySize); arraySize = std::move(other.arraySize);
_data = other._data; _data = other._data;
other._data = nullptr; other._data = nullptr;
refreshIterators(); markIteratorDirty();
} }
return *this; return *this;
} }
@@ -132,15 +148,15 @@ namespace Seele
{ {
return p; return p;
} }
inline bool operator!=(const IteratorBase &other) inline bool operator!=(const IteratorBase &other) const
{ {
return p != other.p; return p != other.p;
} }
inline bool operator==(const IteratorBase &other) inline bool operator==(const IteratorBase &other) const
{ {
return p == other.p; return p == other.p;
} }
inline int operator-(const IteratorBase &other) inline int operator-(const IteratorBase &other) const
{ {
return (int)(p - other.p); return (int)(p - other.p);
} }
@@ -238,7 +254,7 @@ namespace Seele
_data = tempArray; _data = tempArray;
} }
_data[arraySize++] = item; _data[arraySize++] = item;
refreshIterators(); markIteratorDirty();
return _data[arraySize - 1]; return _data[arraySize - 1];
} }
T &add(T&& item) T &add(T&& item)
@@ -257,7 +273,7 @@ namespace Seele
_data = tempArray; _data = tempArray;
} }
_data[arraySize++] = std::move(item); _data[arraySize++] = std::move(item);
refreshIterators(); markIteratorDirty();
return _data[arraySize - 1]; return _data[arraySize - 1];
} }
T &addUnique(const T &item = T()) T &addUnique(const T &item = T())
@@ -286,7 +302,7 @@ namespace Seele
_data = tempArray; _data = tempArray;
} }
_data[arraySize++] = T(arguments...); _data[arraySize++] = T(arguments...);
refreshIterators(); markIteratorDirty();
return _data[arraySize - 1]; return _data[arraySize - 1];
} }
void remove(Iterator it, bool keepOrder = true) void remove(Iterator it, bool keepOrder = true)
@@ -314,7 +330,7 @@ namespace Seele
_data = nullptr; _data = nullptr;
arraySize = 0; arraySize = 0;
allocated = 0; allocated = 0;
refreshIterators(); markIteratorDirty();
} }
void resize(size_t newSize) void resize(size_t newSize)
{ {
@@ -335,7 +351,7 @@ namespace Seele
delete _data; delete _data;
_data = newData; _data = newData;
} }
refreshIterators(); markIteratorDirty();
} }
inline size_t indexOf(Iterator iterator) inline size_t indexOf(Iterator iterator)
{ {
@@ -369,21 +385,21 @@ namespace Seele
{ {
return _data; return _data;
} }
T &back() const inline T &back() const
{ {
return _data[arraySize - 1]; return _data[arraySize - 1];
} }
void pop() void pop()
{ {
arraySize--; arraySize--;
refreshIterators(); markIteratorDirty();
} }
T &operator[](size_t index) constexpr inline T &operator[](size_t index)
{ {
assert(index < arraySize); assert(index < arraySize);
return _data[index]; return _data[index];
} }
const T &operator[](size_t index) const constexpr inline const T &operator[](size_t index) const
{ {
assert(index < arraySize); assert(index < arraySize);
return _data[index]; return _data[index];
@@ -407,7 +423,7 @@ namespace Seele
return geometric; // geometric growth is sufficient return geometric; // geometric growth is sufficient
} }
void refreshIterators() void markIteratorDirty()
{ {
beginIt = Iterator(_data); beginIt = Iterator(_data);
endIt = Iterator(_data + arraySize); endIt = Iterator(_data + arraySize);
@@ -416,18 +432,17 @@ namespace Seele
template<class Archive> template<class Archive>
void serialize(Archive& ar, const unsigned int version) void serialize(Archive& ar, const unsigned int version)
{ {
ar & version;
ar & arraySize; ar & arraySize;
resize(arraySize); resize(arraySize);
for(size_t i = 0; i < arraySize; ++i) for(size_t i = 0; i < arraySize; ++i)
ar & _data[i]; ar & _data[i];
refreshIterators(); markIteratorDirty();
} }
size_t arraySize; size_t arraySize = 0;
size_t allocated; size_t allocated = 0;
Iterator beginIt; Iterator beginIt;
Iterator endIt; Iterator endIt;
T *_data; T *_data = nullptr;
}; };
template <typename T, size_t N> template <typename T, size_t N>
+5 -5
View File
@@ -203,7 +203,7 @@ public:
tail->next = newTail; tail->next = newTail;
Iterator insertedElement(tail); Iterator insertedElement(tail);
tail = newTail; tail = newTail;
refreshIterators(); markIteratorDirty();
_size++; _size++;
return insertedElement; return insertedElement;
} }
@@ -221,7 +221,7 @@ public:
tail->next = newTail; tail->next = newTail;
Iterator insertedElement(tail); Iterator insertedElement(tail);
tail = newTail; tail = newTail;
refreshIterators(); markIteratorDirty();
_size++; _size++;
return insertedElement; return insertedElement;
} }
@@ -247,7 +247,7 @@ public:
next->prev = prev; next->prev = prev;
} }
delete pos.node; delete pos.node;
refreshIterators(); markIteratorDirty();
return Iterator(next); return Iterator(next);
} }
void popBack() void popBack()
@@ -270,7 +270,7 @@ public:
root->prev = nullptr; root->prev = nullptr;
tail->prev = root; tail->prev = root;
tail->next = nullptr; tail->next = nullptr;
refreshIterators(); markIteratorDirty();
return beginIt; return beginIt;
} }
Node *tmp = pos.node->prev; Node *tmp = pos.node->prev;
@@ -319,7 +319,7 @@ public:
} }
private: private:
void refreshIterators() void markIteratorDirty()
{ {
beginIt = Iterator(root); beginIt = Iterator(root);
endIt = Iterator(tail); endIt = Iterator(tail);
+68 -22
View File
@@ -110,16 +110,22 @@ private:
public: public:
Map() Map()
: root(nullptr), _size(0) : root(nullptr)
, _size(0)
, iteratorsDirty(false)
, beginIt(nullptr)
, endIt(nullptr)
{ {
} }
Map(const Map& other) Map(const Map& other)
: root(new Node(*other.root)), _size(other._size) : root(new Node(*other.root))
, _size(other._size)
{ {
refreshIterators(); refreshIterators();
} }
Map(Map&& other) Map(Map&& other)
: root(std::move(other.root)), _size(other._size) : root(std::move(other.root))
, _size(other._size)
{ {
refreshIterators(); refreshIterators();
} }
@@ -137,7 +143,7 @@ public:
} }
root = new Node(*other.root); root = new Node(*other.root);
_size = other.size; _size = other.size;
refreshIterators(); markIteratorDirty();
} }
return *this; return *this;
} }
@@ -151,21 +157,21 @@ public:
} }
root = new Node(std::move(*other.root)); root = new Node(std::move(*other.root));
_size = std::move(other._size); _size = std::move(other._size);
refreshIterators(); markIteratorDirty();
} }
return *this; return *this;
} }
class Iterator class Iterator
{ {
public: public:
typedef std::bidirectional_iterator_tag iterator_category; using iterator_category = std::bidirectional_iterator_tag;
typedef Pair<K, V> value_type; using value_type = Pair<K, V>;
typedef std::ptrdiff_t difference_type; using difference_type = std::ptrdiff_t;
typedef Pair<K, V> &reference; using reference = Pair<K, V>&;
typedef Pair<K, V> *pointer; using pointer = Pair<K, V>*;
Iterator(Node *x = nullptr) Iterator(Node *x = nullptr)
: node(x) : node(x), traversal(Init_t::NO_INIT)
{ {
} }
Iterator(Node *x, Array<Node *> &&beginIt) Iterator(Node *x, Array<Node *> &&beginIt)
@@ -261,31 +267,32 @@ public:
Node *node; Node *node;
Array<Node *> traversal; Array<Node *> traversal;
}; };
V &operator[](const K& key) inline V &operator[](const K& key)
{ {
root = splay(root, key); root = splay(root, key);
markIteratorDirty();
if (root == nullptr || root->pair.key < key || key < root->pair.key) if (root == nullptr || root->pair.key < key || key < root->pair.key)
{ {
root = insert(root, key); root = insert(root, key);
_size++; _size++;
refreshIterators();
} }
return root->pair.value; return root->pair.value;
} }
V &operator[](K&& key) inline V &operator[](K&& key)
{ {
root = splay(root, std::forward<K>(key)); root = splay(root, std::forward<K>(key));
markIteratorDirty();
if (root == nullptr || root->pair.key < key || key < root->pair.key) if (root == nullptr || root->pair.key < key || key < root->pair.key)
{ {
root = insert(root, std::forward<K>(key)); root = insert(root, std::forward<K>(key));
_size++; _size++;
refreshIterators();
} }
return root->pair.value; return root->pair.value;
} }
Iterator find(const K& key) Iterator find(const K& key)
{ {
root = splay(root, key); root = splay(root, key);
markIteratorDirty();
if (root == nullptr || root->pair.key != key) if (root == nullptr || root->pair.key != key)
{ {
return endIt; return endIt;
@@ -295,6 +302,7 @@ public:
Iterator find(K&& key) Iterator find(K&& key)
{ {
root = splay(root, std::move(key)); root = splay(root, std::move(key));
markIteratorDirty();
if (root == nullptr || root->pair.key != key) if (root == nullptr || root->pair.key != key)
{ {
return endIt; return endIt;
@@ -304,13 +312,13 @@ public:
Iterator erase(const K& key) Iterator erase(const K& key)
{ {
root = remove(root, key); root = remove(root, key);
refreshIterators(); markIteratorDirty();
return Iterator(root); return Iterator(root);
} }
Iterator erase(K&& key) Iterator erase(K&& key)
{ {
root = remove(root, std::move(key)); root = remove(root, std::move(key));
refreshIterators(); markIteratorDirty();
return Iterator(root); return Iterator(root);
} }
void clear() void clear()
@@ -318,18 +326,42 @@ public:
delete root; delete root;
root = nullptr; root = nullptr;
_size = 0; _size = 0;
refreshIterators(); markIteratorDirty();
} }
bool exists(K&& key) bool exists(K&& key)
{ {
return find(std::forward<K>(key)) != endIt; return find(std::forward<K>(key)) != endIt;
} }
Iterator begin()
{
if(iteratorsDirty)
{
refreshIterators();
}
return beginIt;
}
Iterator end()
{
if(iteratorsDirty)
{
refreshIterators();
}
return endIt;
}
Iterator begin() const Iterator begin() const
{ {
if(iteratorsDirty)
{
return calcBeginIterator();
}
return beginIt; return beginIt;
} }
Iterator end() const Iterator end() const
{ {
if(iteratorsDirty)
{
return calcEndIterator();
}
return endIt; return endIt;
} }
bool empty() const bool empty() const
@@ -342,12 +374,22 @@ public:
} }
private: private:
void markIteratorDirty()
{
iteratorsDirty = true;
}
void refreshIterators() void refreshIterators()
{
beginIt = calcBeginIterator();
endIt = calcEndIterator();
iteratorsDirty = false;
}
inline Iterator calcBeginIterator() const
{ {
Node *beginNode = root; Node *beginNode = root;
if (root == nullptr) if (root == nullptr)
{ {
beginIt = Iterator(nullptr); return Iterator(nullptr);
} }
else else
{ {
@@ -359,12 +401,15 @@ private:
} }
beginNode = beginTraversal.back(); beginNode = beginTraversal.back();
beginTraversal.pop(); beginTraversal.pop();
beginIt = Iterator(beginNode, std::move(beginTraversal)); return Iterator(beginNode, std::move(beginTraversal));
} }
}
inline Iterator calcEndIterator() const
{
Node *endNode = root; Node *endNode = root;
if (root == nullptr) if (root == nullptr)
{ {
endIt = Iterator(nullptr); return Iterator(nullptr);
} }
else else
{ {
@@ -374,12 +419,13 @@ private:
endTraversal.add(endNode); endTraversal.add(endNode);
endNode = endNode->rightChild; endNode = endNode->rightChild;
} }
endIt = Iterator(endNode, std::move(endTraversal)); return Iterator(endNode, std::move(endTraversal));
} }
} }
Node *root; Node *root;
Iterator beginIt; Iterator beginIt;
Iterator endIt; Iterator endIt;
bool iteratorsDirty;
uint32 _size; uint32 _size;
Node *rotateRight(Node *node) Node *rotateRight(Node *node)
{ {
+1 -1
View File
@@ -22,7 +22,7 @@ struct GraphicsInitializer
GraphicsInitializer() GraphicsInitializer()
: applicationName("SeeleEngine") : applicationName("SeeleEngine")
, engineName("SeeleEngine") , engineName("SeeleEngine")
, layers{"VK_LAYER_KHRONOS_validation"} , layers{"VK_LAYER_KHRONOS_validation", "VK_LAYER_LUNARG_monitor"}
, instanceExtensions{} , instanceExtensions{}
, deviceExtensions{"VK_KHR_swapchain"} , deviceExtensions{"VK_KHR_swapchain"}
, windowHandle(nullptr) , windowHandle(nullptr)
+1 -1
View File
@@ -73,7 +73,7 @@ ShaderCollection& ShaderMap::createShaders(
collection.fragmentShader = graphics->createFragmentShader(createInfo); collection.fragmentShader = graphics->createFragmentShader(createInfo);
} }
ShaderPermutation permutation; ShaderPermutation permutation;
std::string materialName = material->getFileName(); //Filename is fine, because it just has to be unique std::string materialName = material->getName();
std::string vertexInputName = vertexInput->getName(); std::string vertexInputName = vertexInput->getName();
permutation.passType = renderPass; permutation.passType = renderPass;
std::memcpy(permutation.materialName, materialName.c_str(), sizeof(permutation.materialName)); std::memcpy(permutation.materialName, materialName.c_str(), sizeof(permutation.materialName));
+1 -1
View File
@@ -486,7 +486,7 @@ class RenderCommand
public: public:
RenderCommand(); RenderCommand();
virtual ~RenderCommand(); virtual ~RenderCommand();
virtual void begin() = 0; virtual bool isReady() = 0;
virtual void setViewport(Gfx::PViewport viewport) = 0; virtual void setViewport(Gfx::PViewport viewport) = 0;
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) = 0; virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) = 0;
virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0; virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0;
+1
View File
@@ -1,4 +1,5 @@
#include "Mesh.h" #include "Mesh.h"
#include "VertexShaderInput.h"
using namespace Seele; using namespace Seele;
+1 -13
View File
@@ -42,18 +42,7 @@ void BasePassMeshProcessor::addMeshBatch(
descriptorSet->writeChanges(); descriptorSet->writeChanges();
cachedPrimitiveSets.add(descriptorSet); cachedPrimitiveSets.add(descriptorSet);
} }
Gfx::PRenderCommand renderCommand; Gfx::PRenderCommand renderCommand = graphics->createRenderCommand();
if (cachedCommandBuffers.size() > 0)
{
renderCommand = cachedCommandBuffers.back();
cachedCommandBuffers.pop();
renderCommand->begin();
}
else
{
renderCommand = graphics->createRenderCommand();
renderCommand->begin();
}
renderCommand->setViewport(target); renderCommand->setViewport(target);
for(uint32 i = 0; i < batch.elements.size(); ++i) for(uint32 i = 0; i < batch.elements.size(); ++i)
{ {
@@ -84,7 +73,6 @@ Array<Gfx::PRenderCommand> BasePassMeshProcessor::getRenderCommands()
void BasePassMeshProcessor::clearCommands() void BasePassMeshProcessor::clearCommands()
{ {
cachedCommandBuffers = renderCommands;
renderCommands.clear(); renderCommands.clear();
cachedPrimitiveSets.clear(); cachedPrimitiveSets.clear();
cachedPrimitiveIndex = 0; cachedPrimitiveIndex = 0;
@@ -22,7 +22,6 @@ public:
void clearCommands(); void clearCommands();
private: private:
Array<Gfx::PRenderCommand> renderCommands; Array<Gfx::PRenderCommand> renderCommands;
Array<Gfx::PRenderCommand> cachedCommandBuffers;
Array<Gfx::PDescriptorSet> cachedPrimitiveSets; Array<Gfx::PDescriptorSet> cachedPrimitiveSets;
Gfx::PViewport target; Gfx::PViewport target;
uint8 translucentBasePass; uint8 translucentBasePass;
@@ -11,6 +11,7 @@ target_sources(SeeleEngine
VulkanGraphics.cpp VulkanGraphics.cpp
VulkanGraphicsResources.h VulkanGraphicsResources.h
VulkanGraphicsResources.cpp VulkanGraphicsResources.cpp
VulkanDescriptorSets.h
VulkanDescriptorSets.cpp VulkanDescriptorSets.cpp
VulkanGraphicsEnums.h VulkanGraphicsEnums.h
VulkanGraphicsEnums.cpp VulkanGraphicsEnums.cpp
@@ -91,12 +91,15 @@ void CmdBuffer::executeCommands(Array<Gfx::PRenderCommand> commands)
for (uint32 i = 0; i < commands.size(); ++i) for (uint32 i = 0; i < commands.size(); ++i)
{ {
auto command = commands[i].cast<SecondaryCmdBuffer>(); auto command = commands[i].cast<SecondaryCmdBuffer>();
// Cache array and size to save on pointer access
DescriptorSet** boundDescriptors = command->boundDescriptors.data();
size_t numDescriptors = command->boundDescriptors.size();
for(size_t i = 0; i < numDescriptors; ++i)
{
boundDescriptors[i]->currentlyBound = true;
}
command->end(); command->end();
executingCommands.add(command); executingCommands.add(command);
for(PDescriptorSet set : command->boundDescriptors)
{
set->setCurrentlyBound(this);
}
cmdBuffers[i] = command->getHandle(); cmdBuffers[i] = command->getHandle();
} }
vkCmdExecuteCommands(handle, (uint32)cmdBuffers.size(), cmdBuffers.data()); vkCmdExecuteCommands(handle, (uint32)cmdBuffers.size(), cmdBuffers.data());
@@ -114,14 +117,14 @@ void CmdBuffer::refreshFence()
{ {
if (fence->isSignaled()) if (fence->isSignaled())
{ {
state = State::ReadyBegin;
vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT); vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
fence->reset();
for(auto command : executingCommands) for(auto command : executingCommands)
{ {
command->reset(); command->reset();
} }
executingCommands.clear(); executingCommands.clear();
fence->reset(); state = State::ReadyBegin;
} }
} }
else else
@@ -142,6 +145,7 @@ PCommandBufferManager CmdBuffer::getManager()
SecondaryCmdBuffer::SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool) SecondaryCmdBuffer::SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool)
: CmdBufferBase(graphics, cmdPool) : CmdBufferBase(graphics, cmdPool)
, ready(true)
{ {
VkCommandBufferAllocateInfo allocInfo = VkCommandBufferAllocateInfo allocInfo =
init::CommandBufferAllocateInfo(cmdPool, init::CommandBufferAllocateInfo(cmdPool,
@@ -157,6 +161,7 @@ SecondaryCmdBuffer::~SecondaryCmdBuffer()
void SecondaryCmdBuffer::begin(PCmdBuffer parent) void SecondaryCmdBuffer::begin(PCmdBuffer parent)
{ {
ready = false;
VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo beginInfo =
init::CommandBufferBeginInfo(); init::CommandBufferBeginInfo();
VkCommandBufferInheritanceInfo inheritanceInfo = VkCommandBufferInheritanceInfo inheritanceInfo =
@@ -176,15 +181,20 @@ void SecondaryCmdBuffer::end()
void SecondaryCmdBuffer::reset() void SecondaryCmdBuffer::reset()
{ {
for(auto descriptor : boundDescriptors) vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
size_t numBoundDescriptors = boundDescriptors.size();
DescriptorSet** boundDescriptorSets = boundDescriptors.data();
for(size_t i = 0; i < numBoundDescriptors; ++i)
{ {
descriptor->releaseFromCmd(); boundDescriptorSets[i]->currentlyBound = false;
} }
boundDescriptors.clear();
ready = true;
} }
void SecondaryCmdBuffer::begin() bool SecondaryCmdBuffer::isReady()
{ {
begin(graphics->getGraphicsCommands()->getCommands()); return ready;
} }
void SecondaryCmdBuffer::setViewport(Gfx::PViewport viewport) void SecondaryCmdBuffer::setViewport(Gfx::PViewport viewport)
@@ -203,7 +213,7 @@ void SecondaryCmdBuffer::bindPipeline(Gfx::PGraphicsPipeline gfxPipeline)
void SecondaryCmdBuffer::bindDescriptor(Gfx::PDescriptorSet descriptorSet) void SecondaryCmdBuffer::bindDescriptor(Gfx::PDescriptorSet descriptorSet)
{ {
auto descriptor = descriptorSet.cast<DescriptorSet>(); auto descriptor = descriptorSet.cast<DescriptorSet>();
boundDescriptors.add(descriptor); boundDescriptors.add(descriptor.getHandle());
VkDescriptorSet setHandle = descriptor->getHandle(); VkDescriptorSet setHandle = descriptor->getHandle();
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), descriptorSet->getSetIndex(), 1, &setHandle, 0, nullptr); vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), descriptorSet->getSetIndex(), 1, &setHandle, 0, nullptr);
} }
@@ -213,7 +223,7 @@ void SecondaryCmdBuffer::bindDescriptor(const Array<Gfx::PDescriptorSet>& descri
for(uint32 i = 0; i < descriptorSets.size(); ++i) for(uint32 i = 0; i < descriptorSets.size(); ++i)
{ {
auto descriptorSet = descriptorSets[i].cast<DescriptorSet>(); auto descriptorSet = descriptorSets[i].cast<DescriptorSet>();
boundDescriptors.add(descriptorSet); boundDescriptors.add(descriptorSet.getHandle());
sets[descriptorSet->getSetIndex()] = descriptorSet->getHandle(); sets[descriptorSet->getSetIndex()] = descriptorSet->getHandle();
} }
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets, 0, nullptr); vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets, 0, nullptr);
@@ -271,7 +281,20 @@ PCmdBuffer CommandBufferManager::getCommands()
PSecondaryCmdBuffer CommandBufferManager::createSecondaryCmdBuffer() PSecondaryCmdBuffer CommandBufferManager::createSecondaryCmdBuffer()
{ {
return new SecondaryCmdBuffer(graphics, commandPool); std::scoped_lock lck(allocatedSecondBufferLock);
for (uint32 i = 0; i < allocatedSecondBuffers.size(); ++i)
{
PSecondaryCmdBuffer cmdBuffer = allocatedSecondBuffers[i];
if (cmdBuffer->isReady())
{
cmdBuffer->begin(activeCmdBuffer);
return cmdBuffer;
}
}
PSecondaryCmdBuffer result = new SecondaryCmdBuffer(graphics, commandPool);
allocatedSecondBuffers.add(result);
result->begin(activeCmdBuffer);
return result;
} }
void CommandBufferManager::submitCommands(PSemaphore signalSemaphore) void CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
@@ -293,7 +316,7 @@ void CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
queue->submitCommandBuffer(activeCmdBuffer); queue->submitCommandBuffer(activeCmdBuffer);
} }
} }
std::lock_guard lock(allocatedBufferLock); std::scoped_lock lock(allocatedBufferLock);
for (uint32 i = 0; i < allocatedBuffers.size(); ++i) for (uint32 i = 0; i < allocatedBuffers.size(); ++i)
{ {
PCmdBuffer cmdBuffer = allocatedBuffers[i]; PCmdBuffer cmdBuffer = allocatedBuffers[i];
@@ -80,7 +80,7 @@ public:
void begin(PCmdBuffer parent); void begin(PCmdBuffer parent);
void end(); void end();
void reset(); void reset();
virtual void begin() override; virtual bool isReady() override;
virtual void setViewport(Gfx::PViewport viewport) override; virtual void setViewport(Gfx::PViewport viewport) override;
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override; virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override;
virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet) override; virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet) override;
@@ -91,7 +91,8 @@ public:
private: private:
PGraphicsPipeline pipeline; PGraphicsPipeline pipeline;
Array<PDescriptorSet> boundDescriptors; Array<DescriptorSet*> boundDescriptors;
bool ready;
friend class CmdBuffer; friend class CmdBuffer;
}; };
DEFINE_REF(SecondaryCmdBuffer) DEFINE_REF(SecondaryCmdBuffer)
@@ -118,6 +119,8 @@ private:
PCmdBuffer activeCmdBuffer; PCmdBuffer activeCmdBuffer;
std::mutex allocatedBufferLock; std::mutex allocatedBufferLock;
Array<PCmdBuffer> allocatedBuffers; Array<PCmdBuffer> allocatedBuffers;
std::mutex allocatedSecondBufferLock;
Array<PSecondaryCmdBuffer> allocatedSecondBuffers;
}; };
DEFINE_REF(CommandBufferManager) DEFINE_REF(CommandBufferManager)
} // namespace Vulkan } // namespace Vulkan
@@ -171,8 +171,10 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
TextureHandle* cachedTexture = reinterpret_cast<TextureHandle*>(cachedData[Gfx::currentFrameIndex][binding]); TextureHandle* cachedTexture = reinterpret_cast<TextureHandle*>(cachedData[Gfx::currentFrameIndex][binding]);
if(vulkanTexture == cachedTexture) if(vulkanTexture == cachedTexture)
{ {
std::cout << "Cached texture is same as new one, skipping update" << std::endl;
return; return;
} }
std::cout << "Texture changed, updating" << std::endl;
//It is assumed that the image is in the correct layout //It is assumed that the image is in the correct layout
VkDescriptorImageInfo imageInfo = VkDescriptorImageInfo imageInfo =
init::DescriptorImageInfo( init::DescriptorImageInfo(
@@ -201,15 +203,16 @@ bool DescriptorSet::operator<(Gfx::PDescriptorSet other)
return this < otherSet.getHandle(); return this < otherSet.getHandle();
} }
uint32 DescriptorSet::getSetIndex() const
{
return owner->getLayout().getSetIndex();
}
void DescriptorSet::writeChanges() void DescriptorSet::writeChanges()
{ {
if (writeDescriptors.size() > 0) if (writeDescriptors.size() > 0)
{ {
if(currentlyBound != nullptr) assert(!isCurrentlyBound());
{
currentlyBound->getManager()->waitForCommands(currentlyBound);
currentlyBound = nullptr;
}
vkUpdateDescriptorSets(graphics->getDevice(), (uint32)writeDescriptors.size(), writeDescriptors.data(), 0, nullptr); vkUpdateDescriptorSets(graphics->getDevice(), (uint32)writeDescriptors.size(), writeDescriptors.data(), 0, nullptr);
writeDescriptors.clear(); writeDescriptors.clear();
imageInfos.clear(); imageInfos.clear();
@@ -220,9 +223,11 @@ void DescriptorSet::writeChanges()
DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout &layout) DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout &layout)
: graphics(graphics) : graphics(graphics)
, layout(layout) , layout(layout)
, currentCachedIndex(0)
{ {
std::memset(&cachedHandles, 0, sizeof(cachedHandles)); for(uint32 i = 0; i < cachedHandles.size(); ++i)
{
cachedHandles[i] = new DescriptorSet(graphics, this);
}
uint32 perTypeSizes[VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT]; // TODO: FIX ENUM uint32 perTypeSizes[VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT]; // TODO: FIX ENUM
std::memset(perTypeSizes, 0, sizeof(perTypeSizes)); std::memset(perTypeSizes, 0, sizeof(perTypeSizes));
@@ -243,7 +248,7 @@ DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout &l
poolSizes.add(size); poolSizes.add(size);
} }
} }
VkDescriptorPoolCreateInfo createInfo = init::DescriptorPoolCreateInfo((uint32)poolSizes.size(), poolSizes.data(), maxSets); VkDescriptorPoolCreateInfo createInfo = init::DescriptorPoolCreateInfo((uint32)poolSizes.size(), poolSizes.data(), maxSets * Gfx::numFramesBuffered);
VK_CHECK(vkCreateDescriptorPool(graphics->getDevice(), &createInfo, nullptr, &poolHandle)); VK_CHECK(vkCreateDescriptorPool(graphics->getDevice(), &createInfo, nullptr, &poolHandle));
} }
@@ -255,30 +260,48 @@ DescriptorAllocator::~DescriptorAllocator()
void DescriptorAllocator::allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet) void DescriptorAllocator::allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet)
{ {
descriptorSet = new DescriptorSet(graphics, this);
PDescriptorSet vulkanSet = descriptorSet.cast<DescriptorSet>();
VkDescriptorSetLayout layoutHandle = layout.getHandle(); VkDescriptorSetLayout layoutHandle = layout.getHandle();
VkDescriptorSetAllocateInfo allocInfo = VkDescriptorSetLayout layoutArray[Gfx::numFramesBuffered];
init::DescriptorSetAllocateInfo(poolHandle, &layoutHandle, 1); for (uint32 i = 0; i < Gfx::numFramesBuffered; i++)
for(uint32 i = 0; i < Gfx::numFramesBuffered; ++i)
{ {
if(cachedHandles[currentCachedIndex] != VK_NULL_HANDLE) layoutArray[i] = layoutHandle;
{
vulkanSet->setHandle[i] = cachedHandles[currentCachedIndex++];
}
else
{
VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &vulkanSet->setHandle[i]));
cachedHandles[currentCachedIndex++] = vulkanSet->setHandle[i];
}
vulkanSet->cachedData[i].resize(layout.bindings.size());
// Not really pretty, but this way the set knows which ones are valid
std::memset(vulkanSet->cachedData[i].data(), 0, sizeof(void*) * vulkanSet->cachedData[i].size());
} }
VkDescriptorSetAllocateInfo allocInfo =
init::DescriptorSetAllocateInfo(poolHandle, layoutArray, Gfx::numFramesBuffered);
for(uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex)
{
if(cachedHandles[setIndex]->isCurrentlyBound() || cachedHandles[setIndex]->isCurrentlyInUse())
{
// Currently in use, skip
continue;
}
if(cachedHandles[setIndex]->getHandle() == VK_NULL_HANDLE)
{
//If it hasnt been initialized, allocate it
VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, cachedHandles[setIndex]->setHandle));
}
cachedHandles[setIndex]->currentlyInUse = true;
descriptorSet = cachedHandles[setIndex];
PDescriptorSet vulkanSet = descriptorSet.cast<DescriptorSet>();
for(uint32 frameIndex = 0; frameIndex < Gfx::numFramesBuffered; ++frameIndex)
{
vulkanSet->cachedData[frameIndex].resize(layout.bindings.size());
// Not really pretty, but this way the set knows which ones are valid
std::memset(vulkanSet->cachedData[frameIndex].data(), 0, sizeof(void*) * vulkanSet->cachedData[frameIndex].size());
}
//Found set, stop searching
return;
}
throw std::logic_error("Out of descriptor sets");
} }
void DescriptorAllocator::reset() void DescriptorAllocator::reset()
{ {
currentCachedIndex = 0; for(uint32 i = 0; i < cachedHandles.size(); ++i)
{
cachedHandles[i]->free();
}
} }
@@ -54,6 +54,60 @@ private:
}; };
DEFINE_REF(PipelineLayout) DEFINE_REF(PipelineLayout)
class DescriptorSet : public Gfx::DescriptorSet
{
public:
DescriptorSet(PGraphics graphics, PDescriptorAllocator owner)
: graphics(graphics), owner(owner), currentlyInUse(false), currentlyBound(nullptr)
{
std::memset(setHandle, 0, sizeof(setHandle));
}
virtual ~DescriptorSet();
virtual void writeChanges();
virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer);
virtual void updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer);
virtual void updateSampler(uint32_t binding, Gfx::PSamplerState samplerState);
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState sampler = nullptr);
virtual bool operator<(Gfx::PDescriptorSet other);
inline bool isCurrentlyBound() const
{
return currentlyBound;
}
inline bool isCurrentlyInUse() const
{
return currentlyInUse;
}
void free()
{
currentlyInUse = false;
}
inline VkDescriptorSet getHandle() const
{
return setHandle[Gfx::currentFrameIndex];
}
virtual uint32 getSetIndex() const;
private:
Array<VkDescriptorImageInfo> imageInfos;
Array<VkDescriptorBufferInfo> bufferInfos;
Array<VkWriteDescriptorSet> writeDescriptors;
// contains the previously bound resources at every binding
// since the layout is fixed, trying to bind a texture to a buffer
// would not work anyways, so casts should be safe
Array<void*> cachedData[Gfx::numFramesBuffered];
VkDescriptorSet setHandle[Gfx::numFramesBuffered];
PGraphics graphics;
PDescriptorAllocator owner;
bool currentlyBound;
bool currentlyInUse;
friend class DescriptorAllocator;
friend class CmdBuffer;
friend class SecondaryCmdBuffer;
};
DEFINE_REF(DescriptorSet)
class DescriptorAllocator : public Gfx::DescriptorAllocator class DescriptorAllocator : public Gfx::DescriptorAllocator
{ {
public: public:
@@ -74,59 +128,10 @@ public:
private: private:
PGraphics graphics; PGraphics graphics;
DescriptorLayout &layout; DescriptorLayout &layout;
uint32 currentCachedIndex;
const static int maxSets = 512; const static int maxSets = 512;
VkDescriptorSet cachedHandles[maxSets]; StaticArray<PDescriptorSet, maxSets> cachedHandles;
VkDescriptorPool poolHandle; VkDescriptorPool poolHandle;
}; };
DEFINE_REF(DescriptorAllocator) DEFINE_REF(DescriptorAllocator)
class DescriptorSet : public Gfx::DescriptorSet
{
public:
DescriptorSet(PGraphics graphics, PDescriptorAllocator owner)
: graphics(graphics), owner(owner)
{
}
virtual ~DescriptorSet();
virtual void writeChanges();
virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer);
virtual void updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer);
virtual void updateSampler(uint32_t binding, Gfx::PSamplerState samplerState);
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState sampler = nullptr);
virtual bool operator<(Gfx::PDescriptorSet other);
void setCurrentlyBound(PCmdBuffer boundBy)
{
currentlyBound = boundBy;
}
void releaseFromCmd()
{
currentlyBound = nullptr;
}
inline VkDescriptorSet getHandle() const
{
return setHandle[Gfx::currentFrameIndex];
}
virtual uint32 getSetIndex() const
{
return owner->getLayout().getSetIndex();
}
private:
Array<VkDescriptorImageInfo> imageInfos;
Array<VkDescriptorBufferInfo> bufferInfos;
Array<VkWriteDescriptorSet> writeDescriptors;
// contains the previously bound resources at every binding
// since the layout is fixed, trying to bind a texture to a buffer
// would not work anyways, so casts should be safe
Array<void*> cachedData[Gfx::numFramesBuffered];
VkDescriptorSet setHandle[Gfx::numFramesBuffered];
PGraphics graphics;
PDescriptorAllocator owner;
PCmdBuffer currentlyBound;
friend class DescriptorAllocator;
};
DEFINE_REF(DescriptorSet)
} // namespace Vulkan } // namespace Vulkan
} // namespace Seele } // namespace Seele
@@ -768,8 +768,15 @@ VkPipelineShaderStageCreateInfo init::PipelineShaderStageCreateInfo(VkShaderStag
#pragma warning(disable : 4100) #pragma warning(disable : 4100)
VkBool32 Seele::Vulkan::debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char *layerPrefix, const char *msg, void *userDataManager) VkBool32 Seele::Vulkan::debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char *layerPrefix, const char *msg, void *userDataManager)
{ {
std::cerr << layerPrefix << ": " << msg << std::endl; if(flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)
return VK_FALSE; {
return VK_FALSE;
}
else
{
std::cerr << layerPrefix << ": " << msg << std::endl;
return VK_FALSE;
}
} }
#pragma warning(default : 4100) #pragma warning(default : 4100)
+36 -35
View File
@@ -22,43 +22,44 @@ Queue::~Queue()
void Queue::submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores, VkSemaphore *signalSemaphores) void Queue::submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores, VkSemaphore *signalSemaphores)
{ {
assert(cmdBuffer->state == CmdBuffer::State::Ended);
PFence fence = cmdBuffer->fence;
assert(!fence->isSignaled());
const VkCommandBuffer cmdBuffers[] = {cmdBuffer->handle};
VkSubmitInfo submitInfo =
init::SubmitInfo();
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = cmdBuffers;
submitInfo.signalSemaphoreCount = static_cast<uint32>(numSignalSemaphores);
submitInfo.pSignalSemaphores = signalSemaphores;
Array<VkSemaphore> waitSemaphores;
if (cmdBuffer->waitSemaphores.size() > 0)
{ {
for (PSemaphore semaphore : cmdBuffer->waitSemaphores) std::scoped_lock lck(queueLock);
assert(cmdBuffer->state == CmdBuffer::State::Ended);
PFence fence = cmdBuffer->fence;
assert(!fence->isSignaled());
const VkCommandBuffer cmdBuffers[] = {cmdBuffer->handle};
VkSubmitInfo submitInfo =
init::SubmitInfo();
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = cmdBuffers;
submitInfo.signalSemaphoreCount = static_cast<uint32>(numSignalSemaphores);
submitInfo.pSignalSemaphores = signalSemaphores;
Array<VkSemaphore> waitSemaphores;
if (cmdBuffer->waitSemaphores.size() > 0)
{ {
waitSemaphores.add(semaphore->getHandle()); for (PSemaphore semaphore : cmdBuffer->waitSemaphores)
{
waitSemaphores.add(semaphore->getHandle());
}
submitInfo.waitSemaphoreCount = static_cast<uint32>(cmdBuffer->waitSemaphores.size());
submitInfo.pWaitSemaphores = waitSemaphores.data();
submitInfo.pWaitDstStageMask = cmdBuffer->waitFlags.data();
} }
submitInfo.waitSemaphoreCount = static_cast<uint32>(cmdBuffer->waitSemaphores.size()); VK_CHECK(vkQueueSubmit(queue, 1, &submitInfo, fence->getHandle()));
submitInfo.pWaitSemaphores = waitSemaphores.data(); cmdBuffer->state = CmdBuffer::State::Submitted;
submitInfo.pWaitDstStageMask = cmdBuffer->waitFlags.data(); cmdBuffer->waitFlags.clear();
cmdBuffer->waitSemaphores.clear();
if (Gfx::waitIdleOnSubmit)
{
fence->wait(200 * 1000ull);
}
cmdBuffer->refreshFence();
graphics->getStagingManager()->clearPending();
} }
VK_CHECK(vkQueueSubmit(queue, 1, &submitInfo, fence->getHandle()));
cmdBuffer->state = CmdBuffer::State::Submitted;
cmdBuffer->waitFlags.clear();
cmdBuffer->waitSemaphores.clear();
if (Gfx::waitIdleOnSubmit)
{
fence->wait(200 * 1000ull);
}
cmdBuffer->refreshFence();
graphics->getStagingManager()->clearPending();
} }
+1
View File
@@ -27,6 +27,7 @@ public:
} }
private: private:
std::mutex queueLock;
PGraphics graphics; PGraphics graphics;
VkQueue queue; VkQueue queue;
uint32 familyIndex; uint32 familyIndex;
+2 -1
View File
@@ -42,6 +42,7 @@ void Material::load()
void Material::compile() void Material::compile()
{ {
setStatus(Status::Loading);
layout = WindowManager::getGraphics()->createDescriptorLayout(); layout = WindowManager::getGraphics()->createDescriptorLayout();
auto& stream = getReadStream(); auto& stream = getReadStream();
json j; json j;
@@ -142,13 +143,13 @@ void Material::compile()
brdf->generateMaterialCode(codeStream, j["code"]); brdf->generateMaterialCode(codeStream, j["code"]);
codeStream << "};"; codeStream << "};";
codeStream.close(); codeStream.close();
setStatus(Status::Ready);
} }
const Gfx::ShaderCollection* Material::getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const const Gfx::ShaderCollection* Material::getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const
{ {
Gfx::ShaderPermutation permutation; Gfx::ShaderPermutation permutation;
permutation.passType = renderPass; permutation.passType = renderPass;
std::string materialName = getFileName();
std::string vertexInputName = vertexInput->getName(); std::string vertexInputName = vertexInput->getName();
std::memcpy(permutation.materialName, materialName.c_str(), sizeof(permutation.materialName)); std::memcpy(permutation.materialName, materialName.c_str(), sizeof(permutation.materialName));
std::memcpy(permutation.vertexInputName, vertexInputName.c_str(), sizeof(permutation.vertexInputName)); std::memcpy(permutation.vertexInputName, vertexInputName.c_str(), sizeof(permutation.vertexInputName));
+6 -3
View File
@@ -29,6 +29,8 @@ extern std::mutex registeredObjectsLock;
namespace Seele namespace Seele
{ {
template <typename T> template <typename T>
class RefPtr;
template <typename T>
class RefObject class RefObject
{ {
public: public:
@@ -98,13 +100,14 @@ public:
delete this; delete this;
} }
} }
inline T *getHandle() const T *getHandle() const
{ {
return handle; return handle;
} }
private: private:
T *handle; T *handle;
std::atomic_uint64_t refCount; std::atomic_uint64_t refCount;
friend class RefPtr<T>;
}; };
template <typename T> template <typename T>
@@ -239,12 +242,12 @@ public:
inline T *operator->() inline T *operator->()
{ {
assert(object != nullptr); assert(object != nullptr);
return object->getHandle(); return object->handle;
} }
inline const T *operator->() const inline const T *operator->() const
{ {
assert(object != nullptr); assert(object != nullptr);
return object->getHandle(); return object->handle;
} }
RefObject<T> *getObject() const RefObject<T> *getObject() const
{ {
@@ -16,11 +16,14 @@ public:
~PrimitiveComponent(); ~PrimitiveComponent();
virtual void notifySceneAttach(PScene scene) override; virtual void notifySceneAttach(PScene scene) override;
Matrix4 getRenderMatrix(); Matrix4 getRenderMatrix();
const Array<StaticMeshBatch>& getStaticMeshes()
Array<StaticMeshBatch> staticMeshes; {
return staticMeshes;
}
private: private:
Array<PMaterialAsset> materials; Array<PMaterialAsset> materials;
Gfx::PUniformBuffer uniformBuffer; Gfx::PUniformBuffer uniformBuffer;
Array<StaticMeshBatch> staticMeshes;
friend class Scene; friend class Scene;
}; };
DEFINE_REF(PrimitiveComponent) DEFINE_REF(PrimitiveComponent)
+1
View File
@@ -1,5 +1,6 @@
#include "RenderPath.h" #include "RenderPath.h"
#include "Graphics/GraphicsResources.h" #include "Graphics/GraphicsResources.h"
#include "Material/MaterialAsset.h"
Seele::RenderPath::RenderPath(Gfx::PGraphics graphics, Gfx::PViewport target) Seele::RenderPath::RenderPath(Gfx::PGraphics graphics, Gfx::PViewport target)
: graphics(graphics), target(target) : graphics(graphics), target(target)