diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index 2d5dcd0f5e00e0870ea3b9cb4ea8d20f2f623c3d..817c3f5840895158f621ae0c022df07c3c97978a 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -270,6 +270,12 @@ namespace vkcv const uint32_t dispatchCount[3], const std::vector<DescriptorSetUsage> &descriptorSetUsages, const PushConstants& pushConstants); + + void recordBeginDebugLabel(const CommandStreamHandle &cmdStream, + const std::string& label, + const std::array<float, 4>& color); + + void recordEndDebugLabel(const CommandStreamHandle &cmdStream); void recordComputeIndirectDispatchToCmdStream( const CommandStreamHandle cmdStream, @@ -320,6 +326,14 @@ namespace vkcv void recordBlitImage(const CommandStreamHandle& cmdStream, const ImageHandle& src, const ImageHandle& dst, SamplerFilterType filterType); + + void setDebugLabel(const BufferHandle &handle, const std::string &label); + void setDebugLabel(const PassHandle &handle, const std::string &label); + void setDebugLabel(const PipelineHandle &handle, const std::string &label); + void setDebugLabel(const DescriptorSetHandle &handle, const std::string &label); + void setDebugLabel(const SamplerHandle &handle, const std::string &label); + void setDebugLabel(const ImageHandle &handle, const std::string &label); + void setDebugLabel(const CommandStreamHandle &handle, const std::string &label); }; } diff --git a/modules/asset_loader/src/vkcv/asset/asset_loader.cpp b/modules/asset_loader/src/vkcv/asset/asset_loader.cpp index 571d965a400de7197b6fb46f163c4099a5b353f1..2ca35bdab791ea18a67f33e53ab17fc485cbad02 100644 --- a/modules/asset_loader/src/vkcv/asset/asset_loader.cpp +++ b/modules/asset_loader/src/vkcv/asset/asset_loader.cpp @@ -107,7 +107,7 @@ namespace vkcv::asset { const std::vector<fx::gltf::BufferView> &bufferViews, std::vector<VertexAttribute> &dst) { for (const auto &attrib : src) { - VertexAttribute att; + VertexAttribute att {}; if (attrib.first == "POSITION") { att.type = PrimitiveType::POSITION; @@ -282,7 +282,7 @@ namespace vkcv::asset { * modes, default is repeat, the other modes aren't available. */ static vkcv::asset::Sampler loadSampler(const fx::gltf::Sampler &src) { - Sampler dst; + Sampler dst {}; dst.minLOD = 0; dst.maxLOD = VK_LOD_CLAMP_NONE; @@ -414,13 +414,13 @@ namespace vkcv::asset { } if (posAccessor.bufferView >= sceneObjects.bufferViews.size()) { - vkcv_log(LogLevel::ERROR, "Access to bufferView out of bounds: %lu", + vkcv_log(LogLevel::ERROR, "Access to bufferView out of bounds: %d", posAccessor.bufferView); return ASSET_ERROR; } const fx::gltf::BufferView& vertexBufferView = sceneObjects.bufferViews[posAccessor.bufferView]; if (vertexBufferView.buffer >= sceneObjects.buffers.size()) { - vkcv_log(LogLevel::ERROR, "Access to buffer out of bounds: %lu", + vkcv_log(LogLevel::ERROR, "Access to buffer out of bounds: %d", vertexBufferView.buffer); return ASSET_ERROR; } @@ -571,7 +571,7 @@ namespace vkcv::asset { texture.sampler = -1; } else if (static_cast<size_t>(textureObject.sampler) >= scene.samplers.size()) { - vkcv_log(LogLevel::ERROR, "Sampler of texture '%s' missing (%s) %d", + vkcv_log(LogLevel::ERROR, "Sampler of texture '%s' missing (%s)", textureObject.name.c_str(), path.c_str()); return ASSET_ERROR; } else { diff --git a/modules/scene/src/vkcv/scene/Scene.cpp b/modules/scene/src/vkcv/scene/Scene.cpp index d6fa2a40a494ef57386e52a306e962a460c66dd6..c0065af5928d9ad2e2c9afd1a1ea44c35d94d799 100644 --- a/modules/scene/src/vkcv/scene/Scene.cpp +++ b/modules/scene/src/vkcv/scene/Scene.cpp @@ -116,6 +116,10 @@ namespace vkcv::scene { size_t pushConstantsSizePerDrawcall, const RecordMeshDrawcallFunction &record, const std::vector<ImageHandle> &renderTargets) { + m_core->recordBeginDebugLabel(cmdStream, "vkcv::scene::Scene", { + 0.0f, 1.0f, 0.0f, 1.0f + }); + PushConstants pushConstants (pushConstantsSizePerDrawcall); std::vector<DrawcallInfo> drawcalls; size_t count = 0; @@ -137,6 +141,8 @@ namespace vkcv::scene { drawcalls, renderTargets ); + + m_core->recordEndDebugLabel(cmdStream); } Scene Scene::create(Core& core) { diff --git a/modules/upscaling/src/vkcv/upscaling/BilinearUpscaling.cpp b/modules/upscaling/src/vkcv/upscaling/BilinearUpscaling.cpp index 9c36acf5d050e3f4f19223020357b6c32534a2de..54df1829006964b30cc1831dc7115e9d5d222a51 100644 --- a/modules/upscaling/src/vkcv/upscaling/BilinearUpscaling.cpp +++ b/modules/upscaling/src/vkcv/upscaling/BilinearUpscaling.cpp @@ -7,7 +7,13 @@ namespace vkcv::upscaling { void BilinearUpscaling::recordUpscaling(const CommandStreamHandle &cmdStream, const ImageHandle &input, const ImageHandle &output) { + m_core.recordBeginDebugLabel(cmdStream, "vkcv::upscaling::BilinearUpscaling", { + 0.0f, 0.0f, 1.0f, 1.0f + }); + m_core.recordBlitImage(cmdStream, input, output, SamplerFilterType::LINEAR); + + m_core.recordEndDebugLabel(cmdStream); } } diff --git a/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp b/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp index 85908a76d51082b09cf5e6b09ac01fbbd4ef9266..b11051273ba6f9e56d3a537931f9d33fff657e43 100644 --- a/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp +++ b/modules/upscaling/src/vkcv/upscaling/FSRUpscaling.cpp @@ -245,6 +245,10 @@ namespace vkcv::upscaling { void FSRUpscaling::recordUpscaling(const CommandStreamHandle& cmdStream, const ImageHandle& input, const ImageHandle& output) { + m_core.recordBeginDebugLabel(cmdStream, "vkcv::upscaling::FSRUpscaling", { + 1.0f, 0.0f, 0.0f, 1.0f + }); + const uint32_t inputWidth = m_core.getImageWidth(input); const uint32_t inputHeight = m_core.getImageHeight(input); @@ -361,6 +365,8 @@ namespace vkcv::upscaling { PushConstants(0) ); } + + m_core.recordEndDebugLabel(cmdStream); } bool FSRUpscaling::isHdrEnabled() const { diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp index 76e860dea27126c943fa6b6a7d5a01f174203920..d1d856b8863badef8a1b01f6277979cde019c4e0 100644 --- a/projects/first_triangle/src/main.cpp +++ b/projects/first_triangle/src/main.cpp @@ -29,6 +29,8 @@ int main(int argc, const char** argv) { uint16_t indices[3] = { 0, 1, 2 }; triangleIndexBuffer.fill(&indices[0], sizeof(indices)); + core.setDebugLabel(triangleIndexBuffer.getHandle(), "Triangle Index Buffer"); + // an example attachment for passes that output to the window const vkcv::AttachmentDescription present_color_attachment( vkcv::AttachmentOperation::STORE, @@ -43,6 +45,8 @@ int main(int argc, const char** argv) { std::cout << "Error. Could not create renderpass. Exiting." << std::endl; return EXIT_FAILURE; } + + core.setDebugLabel(trianglePass, "Triangle Pass"); vkcv::ShaderProgram triangleShaderProgram; vkcv::shader::GLSLCompiler compiler; @@ -75,12 +79,15 @@ int main(int argc, const char** argv) { return EXIT_FAILURE; } + core.setDebugLabel(trianglePipeline, "Triangle Pipeline"); + auto start = std::chrono::system_clock::now(); const vkcv::Mesh renderMesh({}, triangleIndexBuffer.getVulkanHandle(), 3); vkcv::DrawcallInfo drawcall(renderMesh, {},1); const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle(); + core.setDebugLabel(swapchainInput, "Swapchain Image"); vkcv::camera::CameraManager cameraManager(window); uint32_t camIndex0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); @@ -110,6 +117,7 @@ int main(int argc, const char** argv) { pushConstants.appendDrawcall(mvp); auto cmdStream = core.createCommandStream(vkcv::QueueType::Graphics); + core.setDebugLabel(cmdStream, "Render Commands"); core.recordDrawcallsToCmdStream( cmdStream, diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index 851f08a4c0894b6f6753270ba068e9b2dd544574..095fdd2e98e7f48a14c3426c89e3f336b848b463 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -263,9 +263,8 @@ namespace vkcv vk::Device device) { std::vector<vk::ImageView> attachmentsViews; - for (const ImageHandle handle : renderTargets) { - vk::ImageView targetHandle = imageManager.getVulkanImageView(handle); - attachmentsViews.push_back(targetHandle); + for (const ImageHandle& handle : renderTargets) { + attachmentsViews.push_back(imageManager.getVulkanImageView(handle)); } const std::array<uint32_t, 2> widthHeight = getWidthHeightFromRenderTargets(renderTargets, swapchain, imageManager); @@ -287,8 +286,7 @@ namespace vkcv ImageManager& imageManager, const vk::CommandBuffer cmdBuffer) { - for (const ImageHandle handle : renderTargets) { - vk::ImageView targetHandle = imageManager.getVulkanImageView(handle); + for (const ImageHandle& handle : renderTargets) { const bool isDepthImage = isDepthFormat(imageManager.getImageFormat(handle)); const vk::ImageLayout targetLayout = isDepthImage ? vk::ImageLayout::eDepthStencilAttachmentOptimal : vk::ImageLayout::eColorAttachmentOptimal; @@ -501,7 +499,50 @@ namespace vkcv recordCommandsToStream(cmdStreamHandle, submitFunction, nullptr); } + + void Core::recordBeginDebugLabel(const CommandStreamHandle &cmdStream, + const std::string& label, + const std::array<float, 4>& color) { +#ifndef NDEBUG + static PFN_vkCmdBeginDebugUtilsLabelEXT beginDebugLabel = reinterpret_cast<PFN_vkCmdBeginDebugUtilsLabelEXT>( + m_Context.getDevice().getProcAddr("vkCmdBeginDebugUtilsLabelEXT") + ); + + if (!beginDebugLabel) { + return; + } + + auto submitFunction = [&](const vk::CommandBuffer& cmdBuffer) { + const vk::DebugUtilsLabelEXT debug ( + label.c_str(), + color + ); + + beginDebugLabel(cmdBuffer, &(static_cast<const VkDebugUtilsLabelEXT&>(debug))); + }; + recordCommandsToStream(cmdStream, submitFunction, nullptr); +#endif + } + + void Core::recordEndDebugLabel(const CommandStreamHandle &cmdStream) { +#ifndef NDEBUG + static PFN_vkCmdEndDebugUtilsLabelEXT endDebugLabel = reinterpret_cast<PFN_vkCmdEndDebugUtilsLabelEXT>( + m_Context.getDevice().getProcAddr("vkCmdEndDebugUtilsLabelEXT") + ); + + if (!endDebugLabel) { + return; + } + + auto submitFunction = [&](const vk::CommandBuffer& cmdBuffer) { + endDebugLabel(cmdBuffer); + }; + + recordCommandsToStream(cmdStream, submitFunction, nullptr); +#endif + } + void Core::recordComputeIndirectDispatchToCmdStream( const CommandStreamHandle cmdStream, const PipelineHandle computePipeline, @@ -820,4 +861,141 @@ namespace vkcv }, nullptr); } + static void setDebugObjectLabel(const vk::Device& device, const vk::ObjectType& type, + uint64_t handle, const std::string& label) { +#ifndef NDEBUG + static PFN_vkSetDebugUtilsObjectNameEXT setDebugLabel = reinterpret_cast<PFN_vkSetDebugUtilsObjectNameEXT>( + device.getProcAddr("vkSetDebugUtilsObjectNameEXT") + ); + + if (!setDebugLabel) { + return; + } + + const vk::DebugUtilsObjectNameInfoEXT debug ( + type, + handle, + label.c_str() + ); + + setDebugLabel(device, &(static_cast<const VkDebugUtilsObjectNameInfoEXT&>(debug))); +#endif + } + + void Core::setDebugLabel(const BufferHandle &handle, const std::string &label) { + if (!handle) { + vkcv_log(LogLevel::WARNING, "Can't set debug label to invalid handle"); + return; + } + + setDebugObjectLabel( + m_Context.getDevice(), + vk::ObjectType::eBuffer, + reinterpret_cast<uint64_t>(static_cast<VkBuffer>( + m_BufferManager->getBuffer(handle) + )), + label + ); + } + + void Core::setDebugLabel(const PassHandle &handle, const std::string &label) { + if (!handle) { + vkcv_log(LogLevel::WARNING, "Can't set debug label to invalid handle"); + return; + } + + setDebugObjectLabel( + m_Context.getDevice(), + vk::ObjectType::eRenderPass, + reinterpret_cast<uint64_t>(static_cast<VkRenderPass>( + m_PassManager->getVkPass(handle) + )), + label + ); + } + + void Core::setDebugLabel(const PipelineHandle &handle, const std::string &label) { + if (!handle) { + vkcv_log(LogLevel::WARNING, "Can't set debug label to invalid handle"); + return; + } + + setDebugObjectLabel( + m_Context.getDevice(), + vk::ObjectType::ePipeline, + reinterpret_cast<uint64_t>(static_cast<VkPipeline>( + m_PipelineManager->getVkPipeline(handle) + )), + label + ); + } + + void Core::setDebugLabel(const DescriptorSetHandle &handle, const std::string &label) { + if (!handle) { + vkcv_log(LogLevel::WARNING, "Can't set debug label to invalid handle"); + return; + } + + setDebugObjectLabel( + m_Context.getDevice(), + vk::ObjectType::eDescriptorSet, + reinterpret_cast<uint64_t>(static_cast<VkDescriptorSet>( + m_DescriptorManager->getDescriptorSet(handle).vulkanHandle + )), + label + ); + } + + void Core::setDebugLabel(const SamplerHandle &handle, const std::string &label) { + if (!handle) { + vkcv_log(LogLevel::WARNING, "Can't set debug label to invalid handle"); + return; + } + + setDebugObjectLabel( + m_Context.getDevice(), + vk::ObjectType::eSampler, + reinterpret_cast<uint64_t>(static_cast<VkSampler>( + m_SamplerManager->getVulkanSampler(handle) + )), + label + ); + } + + void Core::setDebugLabel(const ImageHandle &handle, const std::string &label) { + if (!handle) { + vkcv_log(LogLevel::WARNING, "Can't set debug label to invalid handle"); + return; + } else + if (handle.isSwapchainImage()) { + vkcv_log(LogLevel::WARNING, "Can't set debug label to swapchain image"); + return; + } + + setDebugObjectLabel( + m_Context.getDevice(), + vk::ObjectType::eImage, + reinterpret_cast<uint64_t>(static_cast<VkImage>( + m_ImageManager->getVulkanImage(handle) + )), + label + ); + } + + void Core::setDebugLabel(const CommandStreamHandle &handle, const std::string &label) { + if (!handle) { + vkcv_log(LogLevel::WARNING, "Can't set debug label to invalid handle"); + return; + } + + setDebugObjectLabel( + m_Context.getDevice(), + vk::ObjectType::eCommandBuffer, + reinterpret_cast<uint64_t>(static_cast<VkCommandBuffer>( + m_CommandStreamManager->getStreamCommandBuffer(handle) + )), + label + ); + } + } diff --git a/src/vkcv/DrawcallRecording.cpp b/src/vkcv/DrawcallRecording.cpp index d89ace3859717f753534402507a713a78bfb6876..ca8b248a06d06c7aed6f8d0e9760645b727a5993 100644 --- a/src/vkcv/DrawcallRecording.cpp +++ b/src/vkcv/DrawcallRecording.cpp @@ -52,8 +52,6 @@ namespace vkcv { } } - - struct MeshShaderFunctions { PFN_vkCmdDrawMeshTasksNV cmdDrawMeshTasks = nullptr; diff --git a/src/vkcv/QueueManager.cpp b/src/vkcv/QueueManager.cpp index 15e958b0de929e53170324ade27a9b3663a15d6a..79e15c9b00e4c67fb956bdcd0e8b1ff05261b2f1 100644 --- a/src/vkcv/QueueManager.cpp +++ b/src/vkcv/QueueManager.cpp @@ -44,7 +44,7 @@ namespace vkcv { std::vector<int> prios; for(auto flag: queueFlags) { int prioCount = 0; - for (int i = 0; i < qFamilyProperties.size(); i++) { + for (size_t i = 0; i < qFamilyProperties.size(); i++) { prioCount += (static_cast<uint32_t>(flag & qFamilyProperties[i].queueFlags) != 0) * qFamilyProperties[i].queueCount; } prios.push_back(prioCount); @@ -65,10 +65,14 @@ namespace vkcv { std::vector<std::vector<int>> queueFamilyStatus, initialQueueFamilyStatus; for (auto qFamily : qFamilyProperties) { - int graphicsCount = int(static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eGraphics) != 0) * qFamily.queueCount; - int computeCount = int(static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eCompute) != 0) * qFamily.queueCount; - int transferCount = int(static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eTransfer) != 0) * qFamily.queueCount; - queueFamilyStatus.push_back({graphicsCount, computeCount, transferCount}); + auto graphicsCount = static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eGraphics) != 0? qFamily.queueCount : 0; + auto computeCount = static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eCompute) != 0? qFamily.queueCount : 0; + auto transferCount = static_cast<uint32_t>(qFamily.queueFlags & vk::QueueFlagBits::eTransfer) != 0? qFamily.queueCount : 0; + queueFamilyStatus.push_back({ + static_cast<int>(graphicsCount), + static_cast<int>(computeCount), + static_cast<int>(transferCount) + }); } initialQueueFamilyStatus = queueFamilyStatus;