3700 FPS here we go
This commit is contained in:
Vendored
+1
-1
@@ -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": {
|
||||||
|
|||||||
Vendored
+20
-1
@@ -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",
|
||||||
|
|||||||
Vendored
+3
-2
@@ -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"
|
||||||
}
|
}
|
||||||
@@ -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/)
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Vendored
+1
-1
Submodule external/assimp updated: 110f8845a2...8f0c6b04b2
@@ -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:
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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,4 +1,5 @@
|
|||||||
#include "Mesh.h"
|
#include "Mesh.h"
|
||||||
|
#include "VertexShaderInput.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
}
|
||||||
@@ -27,6 +27,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::mutex queueLock;
|
||||||
PGraphics graphics;
|
PGraphics graphics;
|
||||||
VkQueue queue;
|
VkQueue queue;
|
||||||
uint32 familyIndex;
|
uint32 familyIndex;
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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,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)
|
||||||
|
|||||||
Reference in New Issue
Block a user