diff --git a/TGEngine/private/graphics/GameGraphicsModule.cpp b/TGEngine/private/graphics/GameGraphicsModule.cpp index e3202e1..f16a93f 100644 --- a/TGEngine/private/graphics/GameGraphicsModule.cpp +++ b/TGEngine/private/graphics/GameGraphicsModule.cpp @@ -389,10 +389,11 @@ void GameGraphicsModule::tick(double time) { void GameGraphicsModule::destroy() {} -std::vector loadSTBI(const std::vector> &data) { +std::vector loadSTBI(const std::vector &data) { std::vector textureInfos; textureInfos.reserve(data.size()); - for (const auto &dataIn : data) { + for (const auto &values : data) { + const auto& dataIn = values.textureInfo; if (dataIn.empty()) { PLOG_FATAL << "Found empty texture!"; exit(-1); @@ -403,6 +404,7 @@ std::vector loadSTBI(const std::vector> &data) { (int *)&info.width, (int *)&info.height, (int *)&info.channel, 0); info.size = info.width * info.height * info.channel; + info.debugInfo = values.debugName; if (info.channel == 3) { PLOG_FATAL << "Texture with 3 channels not supported!"; exit(-1); @@ -743,10 +745,11 @@ inline size_t fromDXGI(ddspp::DXGIFormat format) { throw std::runtime_error("Translation table not found for DXGI!"); } -std::vector loadDDS(const std::vector> &data) { +std::vector loadDDS(const std::vector &data) { std::vector textureInfos; textureInfos.reserve(data.size()); - for (const auto &ddsVec : data) { + for (const auto &values : data) { + const auto& ddsVec = values.textureInfo; if (ddsVec.empty()) { PLOG_ERROR << "Found empty texture"; continue; @@ -766,13 +769,14 @@ std::vector loadDDS(const std::vector> &data) { info.internalFormatOverride = fromDXGI(desc.format); info.mipMapOverrider = desc.numMips; info.blitMode = BlitMode::NONE; + info.debugInfo = values.debugName; textureInfos.push_back(info); } return textureInfos; } std::vector GameGraphicsModule::loadTextures( - const std::vector> &data, const LoadType type) { + const std::vector &data, const LoadType type) { if (data.empty()) return {}; std::vector textureInfos; @@ -797,7 +801,7 @@ std::vector GameGraphicsModule::loadTextures( const std::vector &names, const LoadType type) { const auto amount = names.size(); std::vector localtextureIDs(amount); - std::vector> data; + std::vector data; data.reserve(amount); for (size_t i = 0; i < amount; i++) { const auto &name = names[i]; @@ -820,7 +824,7 @@ std::vector GameGraphicsModule::loadTextures( PLOG_ERROR << "Couldn't find asset: " << name << "!"; continue; } - data.push_back(file); + data.emplace_back(file, name); localtextureIDs[i] = TTextureHolder(); } if (!data.empty()) { @@ -843,7 +847,7 @@ std::vector GameGraphicsModule::addNode(const NodeInfo *nodeInfos, bindings.reserve(count); std::vector bufferInfos(2 * count); auto allocation = nodeHolder.allocate(count); - auto [dataHolder, transform, parent, binding, status, cache, cacheNormal] = + auto [dataHolder, transform, parent, binding, status, cache, cacheNormal, debug] = allocation.iterator; std::fill(status, status + count, 1); for (size_t i = 0; i < count; i++) { @@ -856,6 +860,7 @@ std::vector GameGraphicsModule::addNode(const NodeInfo *nodeInfos, BufferInfo{&cache[i], sizeof(glm::mat4), DataType::Uniform}; bufferInfos[i + count] = BufferInfo{&cacheNormal[i], sizeof(glm::mat4), DataType::Uniform}; + debug[i] = nodeInfo.debugInfo; } const auto allData = apiLayer->pushData(bufferInfos); std::vector nodeHolder(count); diff --git a/TGEngine/private/graphics/Vulkan/VulkanGraphicsModule.cpp b/TGEngine/private/graphics/Vulkan/VulkanGraphicsModule.cpp index 278688a..1ef3be6 100644 --- a/TGEngine/private/graphics/Vulkan/VulkanGraphicsModule.cpp +++ b/TGEngine/private/graphics/Vulkan/VulkanGraphicsModule.cpp @@ -240,26 +240,22 @@ namespace tge::graphics { const auto& memorys = std::get<1>(compactation); for (const auto memory : memorys) { memoryCounter[memory] -= 1; - } - const auto& allMemorys = - std::get<1>(this->bufferDataHolder.internalValues); - std::vector uniqueMemory; - uniqueMemory.reserve(memorys.size()); - std::ranges::unique_copy(memorys, std::back_inserter(uniqueMemory)); - for (const auto memory : uniqueMemory) { - if (memoryCounter[memory] <= 0) { + + const auto value = memoryCounter[memory]; + if (value <= 0) { device.freeMemory(memory); #ifdef DEBUG PLOG_DEBUG << "Check passed for memory [" + std::to_string((size_t)((VkDeviceMemory)memory)) + - "], mc=" << memoryCounter[memory]; -#endif // DEBUG + "], mc=" << value; +#endif // DEBUG1 } else { #ifdef DEBUG - PLOG_WARNING << "Memory counter not <= 0, mc=" << memoryCounter[memory]; + PLOG_WARNING << "Memory counter not <= 0, mc=" << value << ", memory=" << std::to_string((size_t)((VkDeviceMemory)memory)); #endif // DEBUG } } + } } } @@ -338,6 +334,12 @@ namespace tge::graphics { commandBuffer.begin(beginInfo); for (size_t i = 0; i < renderInfoCount; i++) { auto& info = renderInfos[i]; +#ifdef DEBUG + if (debugEnabled && !info.debugName.empty()) { + vk::DebugUtilsLabelEXT labelInfo(info.debugName.c_str(), {0, 1.0, 0.0, 1.0}); + commandBuffer.beginDebugUtilsLabelEXT(labelInfo, dynamicLoader); + } +#endif // DEBUG const std::vector vertexBuffer = bufferDataHolder.get<0>(std::span(info.vertexBuffer)); @@ -389,6 +391,11 @@ namespace tge::graphics { else { commandBuffer.draw(info.indexCount, info.instanceCount, 0, 0); } +#ifdef DEBUG + if(debugEnabled && !info.debugName.empty()) + commandBuffer.endDebugUtilsLabelEXT(dynamicLoader); +#endif // DEBUG + } commandBuffer.end(); @@ -671,7 +678,7 @@ namespace tge::graphics { inline std::vector createInternalImages( VulkanGraphicsModule* vgm, const std::vector& internalImageInfos) { - std::vector> memoryAndOffsets; + std::vector> memoryAndOffsets; memoryAndOffsets.reserve(internalImageInfos.size()); size_t wholeSize = 0; @@ -710,7 +717,7 @@ namespace tge::graphics { } memoryAndOffsets.push_back( - std::make_tuple(depthImageViewCreateInfo, wholeSize)); + std::make_tuple(depthImageViewCreateInfo, wholeSize, imageInfo.debugInfo)); wholeSize += memoryRequirements.size; } @@ -724,10 +731,19 @@ namespace tge::graphics { const auto output = vgm->textureImageHolder.allocate(internalImageInfos.size()); auto [imageItr, viewItr, memoryItr, offsetItr, internalItr] = output.iterator; - for (const auto& [image, offset] : memoryAndOffsets) { + for (const auto& [image, offset, debug] : memoryAndOffsets) { vgm->device.bindImageMemory(image.image, imageMemory, offset); const auto imageView = vgm->device.createImageView(image); +#ifdef DEBUG + if (vgm->debugEnabled && !debug.empty()) { + DebugUtilsObjectNameInfoEXT objectName(ObjectType::eImageView, (uint64_t)(VkImageView)imageView, debug.c_str()); + vgm->device.setDebugUtilsObjectNameEXT(objectName, vgm->dynamicLoader); + + DebugUtilsObjectNameInfoEXT imageName(ObjectType::eImage, (uint64_t)(VkImage)image.image, debug.c_str()); + vgm->device.setDebugUtilsObjectNameEXT(imageName, vgm->dynamicLoader); + } +#endif // DEBUG *(imageItr++) = image.image; *(viewItr++) = imageView; *(memoryItr++) = imageMemory; @@ -801,7 +817,7 @@ namespace tge::graphics { imagesIn[i] = { format, ext, ImageUsageFlagBits::eTransferDst | ImageUsageFlagBits::eSampled, - SampleCountFlagBits::e1, mipMapCount }; + SampleCountFlagBits::e1, mipMapCount, textureInfo.debugInfo }; } const auto internalImageHolder = createInternalImages(this, imagesIn); @@ -1239,11 +1255,19 @@ namespace tge::graphics { return strcmp(x, VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0; }) != end(extensionEnabled)) { PLOG_DEBUG << "Create debug utils!"; - - DispatchLoaderDynamic stat; - stat.vkCreateDebugUtilsMessengerEXT = + debugEnabled = true; + dynamicLoader.vkCreateDebugUtilsMessengerEXT = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr( instance, "vkCreateDebugUtilsMessengerEXT"); + dynamicLoader.vkCmdBeginDebugUtilsLabelEXT = + (PFN_vkCmdBeginDebugUtilsLabelEXT)vkGetInstanceProcAddr( + instance, "vkCmdBeginDebugUtilsLabelEXT"); + dynamicLoader.vkCmdEndDebugUtilsLabelEXT = + (PFN_vkCmdEndDebugUtilsLabelEXT)vkGetInstanceProcAddr( + instance, "vkCmdEndDebugUtilsLabelEXT"); + dynamicLoader.vkSetDebugUtilsObjectNameEXT = + (PFN_vkSetDebugUtilsObjectNameEXT)vkGetInstanceProcAddr( + instance, "vkSetDebugUtilsObjectNameEXT"); const DebugUtilsMessengerCreateInfoEXT debugUtilsMsgCreateInfo( {}, (DebugUtilsMessageSeverityFlagsEXT) @@ -1252,7 +1276,7 @@ namespace tge::graphics { FlagTraits::allFlags, (PFN_vkDebugUtilsMessengerCallbackEXT)debugMessage); debugMessenger = instance.createDebugUtilsMessengerEXT( - debugUtilsMsgCreateInfo, nullptr, stat); + debugUtilsMsgCreateInfo, nullptr, dynamicLoader); } #endif #pragma endregion diff --git a/TGEngine/public/graphics/APILayer.hpp b/TGEngine/public/graphics/APILayer.hpp index dbc238d..ee6e18b 100644 --- a/TGEngine/public/graphics/APILayer.hpp +++ b/TGEngine/public/graphics/APILayer.hpp @@ -45,6 +45,7 @@ struct RenderInfo { shader::TBindingHolder bindingID{}; size_t firstInstance = 0; std::vector constRanges; + std::string debugName{}; }; enum class BlitMode : uint32_t { @@ -61,6 +62,7 @@ struct TextureInfo { size_t internalFormatOverride = 37; uint32_t mipMapOverrider = INVALID_UINT32; BlitMode blitMode = BlitMode::LINEAR; + std::string debugInfo{}; }; enum class FilterSetting { NEAREST, LINEAR }; @@ -104,10 +106,15 @@ enum class DataType { enum class RenderTarget { OPAQUE_TARGET, TRANSLUCENT_TARGET }; +struct BufferDebugInfo { + std::string info; +}; + struct BufferInfo { const void* data = nullptr; size_t size = INVALID_SIZE_T; DataType type = DataType::Invalid; + std::shared_ptr debugInfo; }; struct BufferChange { diff --git a/TGEngine/public/graphics/GameGraphicsModule.hpp b/TGEngine/public/graphics/GameGraphicsModule.hpp index b459a1d..b397507 100644 --- a/TGEngine/public/graphics/GameGraphicsModule.hpp +++ b/TGEngine/public/graphics/GameGraphicsModule.hpp @@ -26,11 +26,17 @@ namespace tge::graphics { glm::quat rotation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f); }; + struct NodeDebugInfo { + std::string name; + void* data; + }; + struct NodeInfo { shader::TBindingHolder bindingID{}; NodeTransform transforms = {}; size_t parent = INVALID_SIZE_T; TNodeHolder parentHolder; + std::shared_ptr debugInfo; }; struct FeatureSet { @@ -39,6 +45,11 @@ namespace tge::graphics { uint32_t mipMapLevels = 4; }; + struct TextureLoadInternal { + std::vector textureInfo; + std::string debugName{}; + }; + enum class LoadType { STBI, DDSPP }; class GameGraphicsModule : public main::Module { @@ -50,8 +61,7 @@ namespace tge::graphics { glm::mat4 viewMatrix; size_t nextNode = 0; DataHolder - nodeHolder; + glm::mat4, std::shared_ptr> nodeHolder; TDataHolder projection; std::vector bufferChange; std::vector(const std::string&)>> @@ -82,7 +92,7 @@ namespace tge::graphics { const std::string& baseDir = "", void* shaderPipe = nullptr); std::vector loadTextures( - const std::vector>& data, + const std::vector& data, const LoadType type = LoadType::STBI); std::vector loadTextures( diff --git a/TGEngine/public/graphics/vulkan/VulkanModuleDef.hpp b/TGEngine/public/graphics/vulkan/VulkanModuleDef.hpp index 3713301..d18472e 100644 --- a/TGEngine/public/graphics/vulkan/VulkanModuleDef.hpp +++ b/TGEngine/public/graphics/vulkan/VulkanModuleDef.hpp @@ -140,6 +140,7 @@ struct InternalImageInfo { ImageUsageFlags usage = ImageUsageFlagBits::eColorAttachment; SampleCountFlagBits sampleCount = SampleCountFlagBits::e1; size_t mipmapCount = 1; + std::string debugInfo; }; class VulkanGraphicsModule : public APILayer { @@ -211,6 +212,12 @@ class VulkanGraphicsModule : public APILayer { uint32_t nextImage = 0; +#ifdef DEBUG + DebugUtilsMessengerEXT debugMessenger; + vk::DispatchLoaderDynamic dynamicLoader; + bool debugEnabled = false; +#endif + bool isInitialiazed = false; bool exitFailed = false; @@ -219,9 +226,6 @@ class VulkanGraphicsModule : public APILayer { int lightCount; } lights; -#ifdef DEBUG - DebugUtilsMessengerEXT debugMessenger; -#endif VulkanGraphicsModule() : APILayer(new shader::VulkanShaderModule(this)) {}