diff --git a/CMakeLists.txt b/CMakeLists.txt index 807455c..5a48877 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,16 +130,20 @@ endif() add_subdirectory(src/) -set(COPY_DLL_COMMAND "true") if(WIN32) - set(COPY_DLL_COMMAND "copy $ $") + add_custom_target(dll_copy ALL + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ + COMMAND_EXPAND_LISTS + DEPENDS Editor slang-build) +else() + add_custom_target(dll_copy ALL + COMMAND ${CMAKE_COMMAND} -E true) endif() add_custom_target(SeeleEngine ALL COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/res $ - COMMAND ${CMAKE_COMMAND} -E ${COPY_DLL_COMMAND} COMMAND_EXPAND_LISTS - DEPENDS Editor slang-build) + DEPENDS Editor slang-build dll_copy) install( TARGETS diff --git a/src/Editor/Asset/FontLoader.cpp b/src/Editor/Asset/FontLoader.cpp index a6b321a..84c9fa7 100644 --- a/src/Editor/Asset/FontLoader.cpp +++ b/src/Editor/Asset/FontLoader.cpp @@ -3,6 +3,7 @@ #include "Asset/FontAsset.h" #include "Asset/AssetRegistry.h" #include "Graphics/Resources.h" +#include "Graphics/Texture.h" #include #include FT_FREETYPE_H @@ -42,6 +43,7 @@ void FontLoader::import(FontImportArgs args, PFontAsset asset) error = FT_New_Face(ft, args.filePath.string().c_str(), 0, &face); assert(!error); FT_Set_Pixel_Sizes(face, 0, 48); + Array usedTextures; for(uint32 c = 0; c < 256; ++c) { if(FT_Load_Char(face, c, FT_LOAD_RENDER)) @@ -70,10 +72,12 @@ void FontLoader::import(FontImportArgs args, PFontAsset asset) imageData.sourceData.size = sizeof(uint8); imageData.sourceData.data = &transparentPixel; } - glyph.texture = graphics->createTexture2D(imageData); + glyph.textureIndex = usedTextures.size(); + usedTextures.add(graphics->createTexture2D(imageData)); } FT_Done_Face(face); FT_Done_FreeType(ft); + asset->setUsedTextures(std::move(usedTextures)); auto stream = AssetRegistry::createWriteStream((std::filesystem::path(asset->getFolderPath()) / asset->getName()).replace_extension("asset").string(), std::ios::binary); diff --git a/src/Editor/Asset/MaterialLoader.cpp b/src/Editor/Asset/MaterialLoader.cpp index d4b7ca9..f738a44 100644 --- a/src/Editor/Asset/MaterialLoader.cpp +++ b/src/Editor/Asset/MaterialLoader.cpp @@ -75,7 +75,7 @@ void MaterialLoader::import(MaterialImportArgs args, PMaterialAsset asset) p->data = std::stof(defaultValue.value().get()); } parameters.add(p->key); - expressions[p->key] = std::move(p); + expressions[param.key()] = std::move(p); } // TODO: ALIGNMENT RULES else if(type.compare("float3") == 0) @@ -92,7 +92,7 @@ void MaterialLoader::import(MaterialImportArgs args, PMaterialAsset asset) p->data = parseVector(defaultValue.value().get().c_str()); } parameters.add(p->key); - expressions[p->key] = std::move(p); + expressions[param.key()] = std::move(p); } else if(type.compare("Texture2D") == 0) { @@ -108,7 +108,7 @@ void MaterialLoader::import(MaterialImportArgs args, PMaterialAsset asset) p->data = AssetRegistry::findTexture(""); // this will return placeholder texture } parameters.add(p->key); - expressions[p->key] = std::move(p); + expressions[param.key()] = std::move(p); } else if(type.compare("SamplerState") == 0) { @@ -116,7 +116,7 @@ void MaterialLoader::import(MaterialImportArgs args, PMaterialAsset asset) layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER); p->data = graphics->createSamplerState({}); parameters.add(p->key); - expressions[p->key] = std::move(p); + expressions[param.key()] = std::move(p); } else { @@ -136,7 +136,7 @@ void MaterialLoader::import(MaterialImportArgs args, PMaterialAsset asset) OConstantExpression c = new ConstantExpression(str, ExpressionType::UNKNOWN); std::string name = std::format("Const{0}", auxKey++); c->key = name; - expressions[c->key] = std::move(c); + expressions[name] = std::move(c); return name; } else diff --git a/src/Editor/Asset/MeshLoader.cpp b/src/Editor/Asset/MeshLoader.cpp index da46245..00e7b0a 100644 --- a/src/Editor/Asset/MeshLoader.cpp +++ b/src/Editor/Asset/MeshLoader.cpp @@ -41,7 +41,7 @@ void MeshLoader::importAsset(MeshImportArgs args) import(args, ref); } -void MeshLoader::loadMaterials(const aiScene* scene, const std::string& baseName, const std::filesystem::path& meshDirectory, const std::string& importPath, Array& globalMaterials) +void MeshLoader::loadMaterials(const aiScene* scene, const std::string& baseName, const std::filesystem::path& meshDirectory, const std::string& importPath, Array& globalMaterials) { using json = nlohmann::json; for(uint32 i = 0; i < scene->mNumMaterials; ++i) @@ -118,7 +118,11 @@ void MeshLoader::loadMaterials(const aiScene* scene, const std::string& baseName .filePath = meshDirectory / outMatFilename, .importPath = importPath, }); - globalMaterials[i] = AssetRegistry::findMaterial(matCode["name"].get()); + PMaterialAsset baseMat = AssetRegistry::findMaterial(matCode["name"].get()); + globalMaterials[i] = baseMat->instantiate(InstantiationParameter{ + .name = std::format("{0}_Inst_0", baseMat->getName()), + .folderPath = baseMat->getFolderPath(), + }); } } @@ -135,11 +139,11 @@ void findMeshRoots(aiNode *node, List &meshNodes) } } -void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array& materials, Array& globalMeshes, Component::Collider& collider) +void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array& materials, Array& globalMeshes, Component::Collider& collider) { for (uint32 meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex) { - aiMesh *mesh = scene->mMeshes[meshIndex]; + aiMesh* mesh = scene->mMeshes[meshIndex]; collider.boundingbox.adjust(Vector(mesh->mAABB.mMin.x, mesh->mAABB.mMin.y, mesh->mAABB.mMin.z)); collider.boundingbox.adjust(Vector(mesh->mAABB.mMax.x, mesh->mAABB.mMax.y, mesh->mAABB.mMax.z)); @@ -152,7 +156,7 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const ArraymNumVertices; ++i) + for (uint32 i = 0; i < mesh->mNumVertices; ++i) { positions[i] = Vector(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z); texCoords[i] = Vector2(mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].x); @@ -184,29 +188,29 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array int8_t - { - auto [it, inserted] = uniqueVertices.insert(index); - if (inserted) { - if (current.numVertices == Gfx::numVerticesPerMeshlet) + auto [it, inserted] = uniqueVertices.insert(index); + if (inserted) { - return -1; - } - current.uniqueVertices[current.numVertices] = index; - return current.numVertices++; - } - else - { - for (uint32 i = 0; i < current.numVertices; ++i) - { - if (current.uniqueVertices[i] == index) + if (current.numVertices == Gfx::numVerticesPerMeshlet) { - return i; + return -1; } + current.uniqueVertices[current.numVertices] = index; + return current.numVertices++; } - assert(false); - } - }; + else + { + for (uint32 i = 0; i < current.numVertices; ++i) + { + if (current.uniqueVertices[i] == index) + { + return i; + } + } + assert(false); + } + }; auto completeMeshlet = [&meshlets, ¤t, &uniqueVertices]() { meshlets.add(current); current = { @@ -214,7 +218,7 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const ArraymNumFaces; ++faceIndex) { auto i1 = insertAndGetIndex(mesh->mFaces[faceIndex].mIndices[0]); @@ -234,13 +238,13 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const ArrayloadMesh(id, meshlets); - + collider.physicsMesh.addCollider(positions, indices, Matrix4(1.0f)); IndexBufferCreateInfo idxInfo; idxInfo.indexType = Gfx::SE_INDEX_TYPE_UINT32; - idxInfo.sourceData.data = (uint8 *)indices.data(); + idxInfo.sourceData.data = (uint8*)indices.data(); idxInfo.sourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER; idxInfo.sourceData.size = sizeof(uint32) * indices.size(); Gfx::OIndexBuffer indexBuffer = graphics->createIndexBuffer(idxInfo); @@ -249,10 +253,7 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const ArrayvertexData = vertexData; globalMeshes[meshIndex]->id = id; - globalMeshes[meshIndex]->referencedMaterial = materials[mesh->mMaterialIndex]->instantiate(InstantiationParameter{ - .name = std::format("{0}_Inst_0", materials[mesh->mMaterialIndex]->getName()), - .folderPath = materials[mesh->mMaterialIndex]->getFolderPath(), - }); + globalMeshes[meshIndex]->referencedMaterial = materials[mesh->mMaterialIndex]; globalMeshes[meshIndex]->meshlets = std::move(meshlets); globalMeshes[meshIndex]->vertexCount = mesh->mNumVertices; globalMeshes[meshIndex]->indexBuffer = std::move(indexBuffer); @@ -314,7 +315,7 @@ void MeshLoader::import(MeshImportArgs args, PMeshAsset meshAsset) aiProcess_FindDegenerates)); const aiScene *scene = importer.ApplyPostProcessing(aiProcess_CalcTangentSpace); - Array globalMaterials(scene->mNumMaterials); + Array globalMaterials(scene->mNumMaterials); loadTextures(scene, args.filePath.parent_path(), args.importPath); loadMaterials(scene, args.filePath.stem().string(), args.filePath.parent_path(), args.importPath, globalMaterials); diff --git a/src/Editor/Asset/MeshLoader.h b/src/Editor/Asset/MeshLoader.h index 00b061b..9ec1060 100644 --- a/src/Editor/Asset/MeshLoader.h +++ b/src/Editor/Asset/MeshLoader.h @@ -10,7 +10,7 @@ namespace Seele { DECLARE_REF(Mesh) DECLARE_REF(MeshAsset) -DECLARE_REF(MaterialAsset) +DECLARE_REF(MaterialInstanceAsset) DECLARE_NAME_REF(Gfx, Graphics) struct MeshImportArgs { @@ -24,9 +24,9 @@ public: ~MeshLoader(); void importAsset(MeshImportArgs args); private: - void loadMaterials(const aiScene* scene, const std::string& baseName, const std::filesystem::path& meshDirectory, const std::string& importPath, Array& globalMaterials); + void loadMaterials(const aiScene* scene, const std::string& baseName, const std::filesystem::path& meshDirectory, const std::string& importPath, Array& globalMaterials); void loadTextures(const aiScene* scene, const std::filesystem::path& meshDirectory, const std::string& importPath); - void loadGlobalMeshes(const aiScene* scene, const Array& materials, Array& globalMeshes, Component::Collider& collider); + void loadGlobalMeshes(const aiScene* scene, const Array& materials, Array& globalMeshes, Component::Collider& collider); void convertAssimpARGB(unsigned char* dst, aiTexel* src, uint32 numPixels); void import(MeshImportArgs args, PMeshAsset meshAsset); diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp index 2180f72..a78093a 100644 --- a/src/Editor/main.cpp +++ b/src/Editor/main.cpp @@ -227,7 +227,7 @@ int main() sceneViewInfo.dimensions.size.y = 720; sceneViewInfo.dimensions.offset.x = 0; sceneViewInfo.dimensions.offset.y = 0; - OGameView sceneView = new Editor::PlayView(graphics, window, sceneViewInfo, binaryPath); + OGameView sceneView = new Editor::PlayView(graphics, window, sceneViewInfo, binaryPath.generic_string()); //ViewportCreateInfo inspectorViewInfo; //inspectorViewInfo.dimensions.size.x = 640; diff --git a/src/Engine/Asset/AssetRegistry.cpp b/src/Engine/Asset/AssetRegistry.cpp index ff72a96..9747591 100644 --- a/src/Engine/Asset/AssetRegistry.cpp +++ b/src/Engine/Asset/AssetRegistry.cpp @@ -21,7 +21,7 @@ AssetRegistry::~AssetRegistry() delete assetRoot; } -void AssetRegistry::init(const std::string& rootFolder, Gfx::PGraphics graphics) +void AssetRegistry::init(std::filesystem::path rootFolder, Gfx::PGraphics graphics) { get().initialize(rootFolder, graphics); } diff --git a/src/Engine/Asset/AssetRegistry.h b/src/Engine/Asset/AssetRegistry.h index 1ce9ce8..54986ef 100644 --- a/src/Engine/Asset/AssetRegistry.h +++ b/src/Engine/Asset/AssetRegistry.h @@ -16,7 +16,7 @@ class AssetRegistry { public: ~AssetRegistry(); - static void init(const std::string& rootFolder, Gfx::PGraphics graphics); + static void init(std::filesystem::path path, Gfx::PGraphics graphics); static std::filesystem::path getRootFolder(); diff --git a/src/Engine/Asset/FontAsset.cpp b/src/Engine/Asset/FontAsset.cpp index fab1011..a9a599f 100644 --- a/src/Engine/Asset/FontAsset.cpp +++ b/src/Engine/Asset/FontAsset.cpp @@ -22,36 +22,35 @@ FontAsset::~FontAsset() void FontAsset::save(ArchiveBuffer& buffer) const { - uint64 numGlyphs = glyphs.size(); - Serialization::save(buffer, numGlyphs); - for (auto& [index, glyph] : glyphs) + Serialization::save(buffer, glyphs); + Serialization::save(buffer, usedTextures.size()); + for (uint32 x = 0; x < usedTextures.size(); ++x) { - Array textureData; ktxTexture2* kTexture; ktxTextureCreateInfo createInfo = { .glInternalformat = 0, - .vkFormat = (uint32_t)glyph.texture->getFormat(), + .vkFormat = (uint32_t)usedTextures[x]->getFormat(), .pDfd = nullptr, - .baseWidth = glyph.texture->getSizeX(), - .baseHeight = glyph.texture->getSizeY(), - .baseDepth = glyph.texture->getSizeZ(), - .numDimensions = glyph.texture->getSizeZ() > 1 ? 3u : glyph.texture->getSizeY() > 1 ? 2u : 1u, - .numLevels = glyph.texture->getMipLevels(), - .numLayers = glyph.texture->getSizeZ(), - .numFaces = glyph.texture->getNumFaces(), + .baseWidth = usedTextures[x]->getSizeX(), + .baseHeight = usedTextures[x]->getSizeY(), + .baseDepth = usedTextures[x]->getSizeZ(), + .numDimensions = usedTextures[x]->getSizeZ() > 1 ? 3u : usedTextures[x]->getSizeY() > 1 ? 2u : 1u, + .numLevels = usedTextures[x]->getMipLevels(), + .numLayers = usedTextures[x]->getSizeZ(), + .numFaces = usedTextures[x]->getNumFaces(), .isArray = false, .generateMipmaps = false, }; ktxTexture2_Create(&createInfo, KTX_TEXTURE_CREATE_ALLOC_STORAGE, &kTexture); - for (uint32 depth = 0; depth < glyph.texture->getSizeZ(); ++depth) + for (uint32 depth = 0; depth < usedTextures[x]->getSizeZ(); ++depth) { - for (uint32 face = 0; face < glyph.texture->getNumFaces(); ++face) + for (uint32 face = 0; face < usedTextures[x]->getNumFaces(); ++face) { // technically, downloading cant be const, because we have to allocate temporary buffers and change layouts // but practically the texture stays the same - glyph.texture->download(0, depth, face, textureData); + usedTextures[x]->download(0, depth, face, textureData); ktxTexture_SetImageFromMemory(ktxTexture(kTexture), 0, depth, face, textureData.data(), textureData.size()); } } @@ -72,26 +71,18 @@ void FontAsset::save(ArchiveBuffer& buffer) const free(texData); - Serialization::save(buffer, index); Serialization::save(buffer, rawData); - Serialization::save(buffer, glyph.size); - Serialization::save(buffer, glyph.bearing); - Serialization::save(buffer, glyph.advance); } } void FontAsset::load(ArchiveBuffer& buffer) { - uint64 numGlyphs = glyphs.size(); - Serialization::load(buffer, numGlyphs); - for (uint64 x = 0; x < numGlyphs; ++x) + Serialization::load(buffer, glyphs); + size_t numTextures; + Serialization::load(buffer, numTextures); + for (uint64 x = 0; x < numTextures; ++x) { - uint32 index; - Serialization::load(buffer, index); - - Glyph& glyph = glyphs[index]; - Array rawTex; Serialization::load(buffer, rawTex); @@ -120,13 +111,29 @@ void FontAsset::load(ArchiveBuffer& buffer) }; Gfx::OTexture2D texture = buffer.getGraphics()->createTexture2D(createInfo); - glyph.texture = texture; usedTextures.add(std::move(texture)); ktxTexture_Destroy(ktxTexture(kTexture)); - - Serialization::load(buffer, glyph.size); - Serialization::load(buffer, glyph.bearing); - Serialization::load(buffer, glyph.advance); } -} \ No newline at end of file +} + +void Seele::FontAsset::setUsedTextures(Array _usedTextures) +{ + usedTextures = std::move(_usedTextures); +} + +void FontAsset::Glyph::save(ArchiveBuffer& buffer) const +{ + Serialization::save(buffer, textureIndex); + Serialization::save(buffer, size); + Serialization::save(buffer, bearing); + Serialization::save(buffer, advance); +} + +void FontAsset::Glyph::load(ArchiveBuffer& buffer) +{ + Serialization::load(buffer, textureIndex); + Serialization::load(buffer, size); + Serialization::load(buffer, bearing); + Serialization::load(buffer, advance); +} diff --git a/src/Engine/Asset/FontAsset.h b/src/Engine/Asset/FontAsset.h index aec72a0..12dce63 100644 --- a/src/Engine/Asset/FontAsset.h +++ b/src/Engine/Asset/FontAsset.h @@ -18,12 +18,16 @@ public: struct Glyph { - Gfx::PTexture2D texture; + uint32 textureIndex; IVector2 size; IVector2 bearing; uint32 advance; + void save(ArchiveBuffer& buffer) const; + void load(ArchiveBuffer& buffer); }; const Map getGlyphData() const { return glyphs; } + Gfx::PTexture2D getTexture(uint32 index) { return usedTextures[index]; } + void setUsedTextures(Array _usedTextures); private: Array usedTextures; Map glyphs; diff --git a/src/Engine/Asset/MaterialInstanceAsset.cpp b/src/Engine/Asset/MaterialInstanceAsset.cpp index 0a39fe8..aa39b81 100644 --- a/src/Engine/Asset/MaterialInstanceAsset.cpp +++ b/src/Engine/Asset/MaterialInstanceAsset.cpp @@ -30,6 +30,7 @@ void MaterialInstanceAsset::load(ArchiveBuffer& buffer) { std::string id; Serialization::load(buffer, id); + material = new MaterialInstance(); material->load(buffer); baseMaterial = AssetRegistry::findMaterial(id); material->setBaseMaterial(baseMaterial); diff --git a/src/Engine/Graphics/Buffer.h b/src/Engine/Graphics/Buffer.h index bae5dd2..1d2db24 100644 --- a/src/Engine/Graphics/Buffer.h +++ b/src/Engine/Graphics/Buffer.h @@ -23,6 +23,7 @@ protected: virtual void executeOwnershipBarrier(QueueType newOwner) = 0; }; +DECLARE_REF(UniformBuffer) class UniformBuffer : public Buffer { public: @@ -30,7 +31,7 @@ public: virtual ~UniformBuffer(); // returns true if an update was performed, false if the old contents == new contents virtual bool updateContents(const DataSource& sourceData); - bool isDataEquals(UniformBuffer* other) + bool isDataEquals(PUniformBuffer other) { if(other == nullptr) { diff --git a/src/Engine/Graphics/Enums.h b/src/Engine/Graphics/Enums.h index ec3af48..cabc738 100644 --- a/src/Engine/Graphics/Enums.h +++ b/src/Engine/Graphics/Enums.h @@ -165,7 +165,7 @@ namespace Gfx { static constexpr bool useAsyncCompute = true; static constexpr bool waitIdleOnSubmit = true; -extern bool useMeshShading = false; // enable if supported +static constexpr bool useMeshShading = true; static constexpr uint32 numFramesBuffered = 3; // meshlet dimensions curated by NVIDIA diff --git a/src/Engine/Graphics/Graphics.h b/src/Engine/Graphics/Graphics.h index 2864797..729851c 100644 --- a/src/Engine/Graphics/Graphics.h +++ b/src/Engine/Graphics/Graphics.h @@ -80,10 +80,11 @@ public: virtual OPipelineLayout createPipelineLayout(PPipelineLayout baseLayout = nullptr) = 0; virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) = 0; - + bool supportMeshShading() const { return meshShadingEnabled; } protected: QueueFamilyMapping queueMapping; OShaderCompiler shaderCompiler; + bool meshShadingEnabled = false; friend class Window; }; DEFINE_REF(Graphics) diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index effa471..2fa05c9 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -75,7 +75,7 @@ void BasePass::render() graphics->beginRenderPass(renderPass); Gfx::ShaderPermutation permutation; permutation.hasFragment = true; - if(Gfx::useMeshShading) + if(graphics->supportMeshShading()) { permutation.useMeshShading = true; permutation.hasTaskShader = true; @@ -115,7 +115,7 @@ void BasePass::render() const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id); assert(collection != nullptr); - if(Gfx::useMeshShading) + if(graphics->supportMeshShading()) { Gfx::MeshPipelineCreateInfo pipelineInfo; pipelineInfo.taskShader = collection->taskShader; diff --git a/src/Engine/Graphics/RenderPass/BasePass.h b/src/Engine/Graphics/RenderPass/BasePass.h index a4c0ed2..07bd30e 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.h +++ b/src/Engine/Graphics/RenderPass/BasePass.h @@ -19,7 +19,7 @@ public: virtual void createRenderPass() override; static void modifyRenderPassMacros(Map& defines); private: - Gfx::PRenderTargetAttachment colorAttachment; + Gfx::ORenderTargetAttachment colorAttachment; Gfx::PTexture2D depthBuffer; Gfx::PShaderBuffer oLightIndexList; Gfx::PShaderBuffer tLightIndexList; diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp index d09db3b..140ccc3 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp @@ -39,7 +39,7 @@ void DepthPrepass::render() depthAttachment->getTexture()->transferOwnership(Gfx::QueueType::GRAPHICS); Gfx::ShaderPermutation permutation; permutation.hasFragment = false; - if(Gfx::useMeshShading) + if(graphics->supportMeshShading()) { permutation.useMeshShading = true; permutation.hasTaskShader = true; @@ -76,7 +76,7 @@ void DepthPrepass::render() const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id); assert(collection != nullptr); - if(Gfx::useMeshShading) + if(graphics->supportMeshShading()) { Gfx::MeshPipelineCreateInfo pipelineInfo; pipelineInfo.taskShader = collection->taskShader; @@ -107,7 +107,7 @@ void DepthPrepass::render() descriptorSets[INDEX_MATERIAL] = instance.materialInstance->getDescriptorSet(); descriptorSets[INDEX_SCENE_DATA] = instance.descriptorSet; command->bindDescriptor(descriptorSets); - if(Gfx::useMeshShading) + if(graphics->supportMeshShading()) { command->dispatch(instance.numMeshes, 1, 1); } diff --git a/src/Engine/Graphics/RenderPass/TextPass.cpp b/src/Engine/Graphics/RenderPass/TextPass.cpp index d051e13..01a8e73 100644 --- a/src/Engine/Graphics/RenderPass/TextPass.cpp +++ b/src/Engine/Graphics/RenderPass/TextPass.cpp @@ -226,7 +226,7 @@ TextPass::FontData& TextPass::getFontData(PFontAsset font) gd.bearing = value.bearing; gd.size = value.size; gd.advance = value.advance; - textures.add(value.texture); + textures.add(font->getTexture(value.textureIndex)); } fd.glyphDataSet = glyphData; diff --git a/src/Engine/Graphics/StaticMeshVertexData.h b/src/Engine/Graphics/StaticMeshVertexData.h index 6c4d4ca..2aacdfc 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.h +++ b/src/Engine/Graphics/StaticMeshVertexData.h @@ -16,7 +16,6 @@ public: void loadNormals(MeshId id, const Array& data); void loadTangents(MeshId id, const Array& data); void loadBiTangents(MeshId id, const Array& data); - virtual Gfx::PVertexDeclaration getDeclaration() override; virtual void serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) override; virtual void deserializeMesh(MeshId id, ArchiveBuffer& buffer) override; virtual void init(Gfx::PGraphics graphics) override; diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index 6922171..9c74895 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -118,7 +118,7 @@ void VertexData::createDescriptors() instanceDataLayout->reset(); matInst.descriptorSet = instanceDataLayout->allocateDescriptorSet(); matInst.descriptorSet->updateBuffer(0, instanceBuffer); - if (Gfx::useMeshShading) + if (graphics->supportMeshShading()) { Gfx::PShaderBuffer meshDataBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ .sourceData = { @@ -181,7 +181,7 @@ void Seele::VertexData::init(Gfx::PGraphics graphics) verticesAllocated = NUM_DEFAULT_ELEMENTS; instanceDataLayout = graphics->createDescriptorLayout("VertexDataInstanceLayout"); instanceDataLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); - if (Gfx::useMeshShading) + if (graphics->supportMeshShading()) { // meshData instanceDataLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); diff --git a/src/Engine/Graphics/Vulkan/Allocator.cpp b/src/Engine/Graphics/Vulkan/Allocator.cpp index 5c46108..723ab83 100644 --- a/src/Engine/Graphics/Vulkan/Allocator.cpp +++ b/src/Engine/Graphics/Vulkan/Allocator.cpp @@ -89,10 +89,8 @@ OSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDevice return nullptr; } } - for (auto& it : freeRanges) + for (auto& [allocatedOffset, freeAllocation] : freeRanges) { - VkDeviceSize allocatedOffset = it.key; - OSubAllocation& freeAllocation = it.value; assert(allocatedOffset == freeAllocation->allocatedOffset); VkDeviceSize alignedOffset = allocatedOffset + alignment - 1; alignedOffset /= alignment; @@ -284,18 +282,18 @@ OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2 return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment); } -void Allocator::free(Allocation *allocation) +void Allocator::free(PAllocation allocation) { std::scoped_lock lck(lock); - for (auto& heap : heaps) + for (uint32 heapIndex = 0; heapIndex < heaps.size(); ++heapIndex) { - for (uint32 heapIndex = 0; heapIndex < heap.allocations.size(); ++heapIndex) + for (uint32 alloc = 0; alloc < heaps[heapIndex].allocations.size(); ++alloc) { - if (heap.allocations[heapIndex] == allocation) + if (heaps[heapIndex].allocations[alloc] == allocation) { - heap.inUse -= allocation->bytesAllocated; - std::cout << "Heap " << heapIndex << " -" <bytesAllocated << ":" << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl; - heap.allocations.removeAt(heapIndex, false); + heaps[heapIndex].inUse -= allocation->bytesAllocated; + std::cout << "Heap " << heapIndex << " -" <bytesAllocated << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl; + heaps[heapIndex].allocations.removeAt(heapIndex, false); return; } } @@ -432,11 +430,11 @@ OStagingBuffer StagingManager::allocateStagingBuffer(uint64 size, VkBufferUsageF void StagingManager::releaseStagingBuffer(OStagingBuffer buffer) { - std::scoped_lock l(lock); - if(activeBuffers.find(buffer) == activeBuffers.end()) + if (buffer == nullptr) { return; } + std::scoped_lock l(lock); activeBuffers.remove(buffer); std::cout << "Releasing stagingbuffer size " << buffer->getSize() << std::endl; freeBuffers.add(std::move(buffer)); diff --git a/src/Engine/Graphics/Vulkan/Allocator.h b/src/Engine/Graphics/Vulkan/Allocator.h index 87a9991..1c86b69 100644 --- a/src/Engine/Graphics/Vulkan/Allocator.h +++ b/src/Engine/Graphics/Vulkan/Allocator.h @@ -128,7 +128,7 @@ public: return allocate(requirements, props, &allocInfo); } - void free(Allocation *allocation); + void free(PAllocation allocation); private: enum { diff --git a/src/Engine/Graphics/Vulkan/Buffer.cpp b/src/Engine/Graphics/Vulkan/Buffer.cpp index 6e1ccb1..ae0c54a 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.cpp +++ b/src/Engine/Graphics/Vulkan/Buffer.cpp @@ -61,20 +61,6 @@ Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::Q Buffer::~Buffer() { - //PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands(); - //VkDevice device = graphics->getDevice(); - //auto deletionLambda = [cmdBuffer, device](VkBuffer) -> void - //{ - // //co_await cmdBuffer->asyncWait(); - // //vkDestroyBuffer(device, buffer, nullptr); - // //co_return; - //}; - //for (uint32 i = 0; i < numBuffers; ++i) - //{ - // deletionLambda(buffers[i].buffer); - // buffers[i].allocation = nullptr; - //} - graphics = nullptr; } VkDeviceSize Buffer::getOffset() const diff --git a/src/Engine/Graphics/Vulkan/Buffer.h b/src/Engine/Graphics/Vulkan/Buffer.h index 46228ba..a701648 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.h +++ b/src/Engine/Graphics/Vulkan/Buffer.h @@ -7,7 +7,6 @@ namespace Seele { namespace Vulkan { - class Buffer { public: diff --git a/src/Engine/Graphics/Vulkan/Graphics.cpp b/src/Engine/Graphics/Vulkan/Graphics.cpp index d2a9d9b..e97b1f1 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.cpp +++ b/src/Engine/Graphics/Vulkan/Graphics.cpp @@ -114,108 +114,95 @@ void Graphics::executeCommands(const Array& commands) Gfx::OTexture2D Graphics::createTexture2D(const TextureCreateInfo &createInfo) { - OTexture2D result = new Texture2D(this, createInfo); - return result; + return new Texture2D(this, createInfo); } Gfx::OTexture3D Graphics::createTexture3D(const TextureCreateInfo &createInfo) { - OTexture3D result = new Texture3D(this, createInfo); - return result; + return new Texture3D(this, createInfo); } Gfx::OTextureCube Graphics::createTextureCube(const TextureCreateInfo &createInfo) { - OTextureCube result = new TextureCube(this, createInfo); - return result; + return new TextureCube(this, createInfo); } Gfx::OUniformBuffer Graphics::createUniformBuffer(const UniformBufferCreateInfo &bulkData) { - OUniformBuffer uniformBuffer = new UniformBuffer(this, bulkData); - return uniformBuffer; + return new UniformBuffer(this, bulkData); } Gfx::OShaderBuffer Graphics::createShaderBuffer(const ShaderBufferCreateInfo &bulkData) { - OShaderBuffer shaderBuffer = new ShaderBuffer(this, bulkData); - return shaderBuffer; + return new ShaderBuffer(this, bulkData); } Gfx::OVertexBuffer Graphics::createVertexBuffer(const VertexBufferCreateInfo &bulkData) { - OVertexBuffer vertexBuffer = new VertexBuffer(this, bulkData); - return vertexBuffer; + return new VertexBuffer(this, bulkData); } Gfx::OIndexBuffer Graphics::createIndexBuffer(const IndexBufferCreateInfo &bulkData) { - OIndexBuffer indexBuffer = new IndexBuffer(this, bulkData); - return indexBuffer; + return new IndexBuffer(this, bulkData); } Gfx::PRenderCommand Graphics::createRenderCommand(const std::string& name) { - PRenderCommand cmdBuffer = getGraphicsCommands()->createRenderCommand(activeRenderPass, activeFramebuffer, name); - return cmdBuffer; + return getGraphicsCommands()->createRenderCommand(activeRenderPass, activeFramebuffer, name); } Gfx::PComputeCommand Graphics::createComputeCommand(const std::string& name) { - PComputeCommand cmdBuffer = getComputeCommands()->createComputeCommand(name); - return cmdBuffer; + return getComputeCommands()->createComputeCommand(name); } Gfx::OVertexDeclaration Graphics::createVertexDeclaration(const Array& element) { - OVertexDeclaration declaration = new VertexDeclaration(element); - return declaration; + return new VertexDeclaration(element); } Gfx::OVertexShader Graphics::createVertexShader(const ShaderCreateInfo& createInfo) { OVertexShader shader = new VertexShader(this); shader->create(createInfo); - return shader; + return std::move(shader); } Gfx::OFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& createInfo) { OFragmentShader shader = new FragmentShader(this); shader->create(createInfo); - return shader; + return std::move(shader); } Gfx::OComputeShader Graphics::createComputeShader(const ShaderCreateInfo& createInfo) { OComputeShader shader = new ComputeShader(this); shader->create(createInfo); - return shader; + return std::move(shader); } Gfx::OTaskShader Graphics::createTaskShader(const ShaderCreateInfo& createInfo) { OTaskShader shader = new TaskShader(this); shader->create(createInfo); - return shader; + return std::move(shader); } Gfx::OMeshShader Graphics::createMeshShader(const ShaderCreateInfo& createInfo) { OMeshShader shader = new MeshShader(this); shader->create(createInfo); - return shader; + return std::move(shader); } Gfx::OGraphicsPipeline Graphics::createGraphicsPipeline(const Gfx::LegacyPipelineCreateInfo& createInfo) { - OGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo); - return pipeline; + return pipelineCache->createPipeline(createInfo); } Gfx::OGraphicsPipeline Graphics::createGraphicsPipeline(const Gfx::MeshPipelineCreateInfo& createInfo) { - OGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo); - return pipeline; + return pipelineCache->createPipeline(createInfo); } Gfx::OComputePipeline Graphics::createComputePipeline(const Gfx::ComputePipelineCreateInfo& createInfo) { - OComputePipeline pipeline = pipelineCache->createPipeline(createInfo); - return pipeline; + return pipelineCache->createPipeline(createInfo); } Gfx::OSamplerState Graphics::createSamplerState(const SamplerCreateInfo& createInfo) @@ -240,17 +227,15 @@ Gfx::OSamplerState Graphics::createSamplerState(const SamplerCreateInfo& createI vkInfo.mipmapMode = cast(createInfo.mipmapMode); vkInfo.unnormalizedCoordinates = createInfo.unnormalizedCoordinates; VK_CHECK(vkCreateSampler(handle, &vkInfo, nullptr, &sampler->sampler)); - return sampler; + return std::move(sampler); } Gfx::ODescriptorLayout Graphics::createDescriptorLayout(const std::string& name) { - ODescriptorLayout layout = new DescriptorLayout(this, name); - return layout; + return new DescriptorLayout(this, name); } Gfx::OPipelineLayout Graphics::createPipelineLayout(Gfx::PPipelineLayout baseLayout) { - OPipelineLayout layout = new PipelineLayout(this, baseLayout); - return layout; + return new PipelineLayout(this, baseLayout); } void Graphics::copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) @@ -469,16 +454,19 @@ void Graphics::pickPhysicalDevice() physicalDevice = bestDevice; vkGetPhysicalDeviceProperties(physicalDevice, &props); vkGetPhysicalDeviceFeatures(physicalDevice, &features); - uint32 count = 0; - vkEnumerateDeviceExtensionProperties(physicalDevice, "VK_EXT_mesh_shader", &count, nullptr); - Array extensionProps(count); - vkEnumerateDeviceExtensionProperties(physicalDevice, "VK_EXT_mesh_shader", &count, extensionProps.data()); - for(size_t i = 0; i < count; ++i) + if (Gfx::useMeshShading) { - if(std::strcmp("VK_EXT_mesh_shader", extensionProps[i].extensionName) == 0) + uint32 count = 0; + vkEnumerateDeviceExtensionProperties(physicalDevice, VK_EXT_MESH_SHADER_EXTENSION_NAME, &count, nullptr); + Array extensionProps(count); + vkEnumerateDeviceExtensionProperties(physicalDevice, VK_EXT_MESH_SHADER_EXTENSION_NAME, &count, extensionProps.data()); + for (size_t i = 0; i < count; ++i) { - Gfx::useMeshShading = true; - break; + if (std::strcmp(VK_EXT_MESH_SHADER_EXTENSION_NAME, extensionProps[i].extensionName) == 0) + { + meshShadingEnabled = true; + break; + } } } } @@ -605,7 +593,7 @@ void Graphics::createDevice(GraphicsInitializer initializer) .taskShader = VK_TRUE, .meshShader = VK_TRUE, }; - if (Gfx::useMeshShading) + if (supportMeshShading()) { descriptorIndexing.pNext = &enabledMeshShaderFeatures; initializer.deviceExtensions.add("VK_EXT_mesh_shader"); diff --git a/src/Engine/Graphics/Vulkan/PipelineCache.cpp b/src/Engine/Graphics/Vulkan/PipelineCache.cpp index 5499ec5..09b53a5 100644 --- a/src/Engine/Graphics/Vulkan/PipelineCache.cpp +++ b/src/Engine/Graphics/Vulkan/PipelineCache.cpp @@ -38,7 +38,7 @@ PipelineCache::~PipelineCache() { VkDeviceSize cacheSize; vkGetPipelineCacheData(graphics->getDevice(), cache, &cacheSize, nullptr); - Array cacheData; + Array cacheData(cacheSize); vkGetPipelineCacheData(graphics->getDevice(), cache, &cacheSize, cacheData.data()); std::ofstream stream(cacheFile, std::ios::binary); stream.write((char*)cacheData.data(), cacheSize); diff --git a/src/Engine/Graphics/Vulkan/RenderTarget.cpp b/src/Engine/Graphics/Vulkan/RenderTarget.cpp index 8ec9e80..7c19c35 100644 --- a/src/Engine/Graphics/Vulkan/RenderTarget.cpp +++ b/src/Engine/Graphics/Vulkan/RenderTarget.cpp @@ -9,7 +9,6 @@ using namespace Seele; using namespace Seele::Vulkan; -double useMeshShading = false; double currentFrameDelta = 0; double Gfx::getCurrentFrameDelta() { diff --git a/src/Engine/Graphics/Vulkan/Texture.cpp b/src/Engine/Graphics/Vulkan/Texture.cpp index 5adc018..e07d49e 100644 --- a/src/Engine/Graphics/Vulkan/Texture.cpp +++ b/src/Engine/Graphics/Vulkan/Texture.cpp @@ -110,7 +110,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, if(sourceData.size > 0) { changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - PStagingBuffer staging = graphics->getStagingManager()->allocateStagingBuffer(sourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); + OStagingBuffer staging = graphics->getStagingManager()->allocateStagingBuffer(sourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); void* data = staging->getMappedPointer(); std::memcpy(data, sourceData.data, sourceData.size); staging->flushMappedMemory(); @@ -134,6 +134,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, // When loading a texture from a file, we will almost always use it as a texture map for fragment shaders changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + graphics->getStagingManager()->releaseStagingBuffer(std::move(staging)); } else if(usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { @@ -213,7 +214,7 @@ void TextureHandle::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Ar { uint64 imageSize = sizeX * sizeY * sizeZ * Gfx::getFormatInfo(format).blockSize; - PStagingBuffer stagingbuffer = graphics->getStagingManager()->allocateStagingBuffer(imageSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true); + OStagingBuffer stagingbuffer = graphics->getStagingManager()->allocateStagingBuffer(imageSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true); auto prevlayout = layout; changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands(); @@ -236,6 +237,7 @@ void TextureHandle::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Ar buffer.resize(stagingbuffer->getSize()); void* data = stagingbuffer->getMappedPointer(); std::memcpy(buffer.data(), data, buffer.size()); + graphics->getStagingManager()->releaseStagingBuffer(std::move(stagingbuffer)); } void TextureHandle::executeOwnershipBarrier(Gfx::QueueType newOwner) diff --git a/src/Engine/MinimalEngine.h b/src/Engine/MinimalEngine.h index 4acfb7e..ddb898e 100644 --- a/src/Engine/MinimalEngine.h +++ b/src/Engine/MinimalEngine.h @@ -145,6 +145,7 @@ public: OwningPtr(OwningPtr&& other) { pointer = dynamic_cast(*other); + other.clear(); } OwningPtr(const OwningPtr& other) = delete; OwningPtr(OwningPtr&& other) noexcept @@ -162,9 +163,14 @@ public: Deleter()(pointer); } pointer = other.pointer; + other.pointer = nullptr; } return *this; } + ~OwningPtr() + { + Deleter()(pointer); + } operator RefPtr() { return RefPtr(pointer); @@ -189,14 +195,19 @@ public: { return pointer; } - constexpr bool operator==(const OwningPtr& rhs) const noexcept + constexpr bool operator==(std::nullptr_t) const noexcept { - return pointer == rhs.pointer; + return pointer == nullptr; } constexpr auto operator<=>(const OwningPtr& rhs) const noexcept { return pointer <=> rhs.pointer; } + // INTERNAL USE + constexpr void clear() + { + pointer = nullptr; + } private: friend class RefPtr; T* pointer;