diff --git a/ScopEngine/Runtime/Includes/Renderer/Buffer.h b/ScopEngine/Runtime/Includes/Renderer/Buffer.h index f97f50f..078f186 100644 --- a/ScopEngine/Runtime/Includes/Renderer/Buffer.h +++ b/ScopEngine/Runtime/Includes/Renderer/Buffer.h @@ -15,7 +15,7 @@ namespace Scop public: GPUBuffer() = default; - void Init(BufferType type, VkDeviceSize size, VkBufferUsageFlags usage, CPUBuffer data); + void Init(BufferType type, VkDeviceSize size, VkBufferUsageFlags usage, CPUBuffer data, std::string_view name = {}); void Destroy() noexcept; bool CopyFrom(const GPUBuffer& buffer) noexcept; @@ -43,11 +43,15 @@ namespace Scop MemoryBlock m_memory = NULL_MEMORY_BLOCK; private: - void CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties); + void CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, std::string_view name); private: inline static std::size_t s_buffer_count = 0; + #ifdef SCOP_HAS_DEBUG_UTILS_FUNCTIONS + std::string m_name; + #endif + VkBufferUsageFlags m_usage = 0; VkMemoryPropertyFlags m_flags = 0; }; @@ -55,7 +59,7 @@ namespace Scop class VertexBuffer : public GPUBuffer { public: - inline void Init(std::uint32_t size, VkBufferUsageFlags additional_flags = 0) { GPUBuffer::Init(BufferType::LowDynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | additional_flags, {}); } + inline void Init(std::uint32_t size, VkBufferUsageFlags additional_flags = 0, std::string_view name = {}) { GPUBuffer::Init(BufferType::LowDynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | additional_flags, {}, std::move(name)); } void SetData(CPUBuffer data); inline void Bind(VkCommandBuffer cmd) const noexcept { VkDeviceSize offset = 0; RenderCore::Get().vkCmdBindVertexBuffers(cmd, 0, 1, &m_buffer, &offset); } }; @@ -63,7 +67,7 @@ namespace Scop class IndexBuffer : public GPUBuffer { public: - inline void Init(std::uint32_t size, VkBufferUsageFlags additional_flags = 0) { GPUBuffer::Init(BufferType::LowDynamic, size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | additional_flags, {}); } + inline void Init(std::uint32_t size, VkBufferUsageFlags additional_flags = 0, std::string_view name = {}) { GPUBuffer::Init(BufferType::LowDynamic, size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | additional_flags, {}, std::move(name)); } void SetData(CPUBuffer data); inline void Bind(VkCommandBuffer cmd) const noexcept { RenderCore::Get().vkCmdBindIndexBuffer(cmd, m_buffer, 0, VK_INDEX_TYPE_UINT32); } }; @@ -71,7 +75,7 @@ namespace Scop class UniformBuffer { public: - void Init(std::uint32_t size); + void Init(std::uint32_t size, std::string_view name = {}); void SetData(CPUBuffer data, std::size_t frame_index); void Destroy() noexcept; diff --git a/ScopEngine/Runtime/Includes/Renderer/Image.h b/ScopEngine/Runtime/Includes/Renderer/Image.h index 1741a66..e603e13 100644 --- a/ScopEngine/Runtime/Includes/Renderer/Image.h +++ b/ScopEngine/Runtime/Includes/Renderer/Image.h @@ -19,16 +19,24 @@ namespace Scop public: Image() = default; - inline void Init(VkImage image, VkFormat format, std::uint32_t width, std::uint32_t height, VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED) noexcept + inline void Init(VkImage image, VkFormat format, std::uint32_t width, std::uint32_t height, VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED, std::string_view name = {}) noexcept { m_image = image; m_format = format; m_width = width; m_height = height; m_layout = layout; + #ifdef SCOP_HAS_DEBUG_UTILS_FUNCTIONS + VkDebugUtilsObjectNameInfoEXT name_info{}; + name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + name_info.objectType = VK_OBJECT_TYPE_IMAGE; + name_info.objectHandle = reinterpret_cast(m_image); + name_info.pObjectName = name.data(); + RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info); + #endif } - void Init(ImageType type, std::uint32_t width, std::uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, bool is_multisampled = false); + void Init(ImageType type, std::uint32_t width, std::uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, bool is_multisampled = false, std::string_view name = {}); void CreateImageView(VkImageViewType type, VkImageAspectFlags aspectFlags, int layer_count = 1) noexcept; void CreateSampler() noexcept; void TransitionLayout(VkImageLayout new_layout, VkCommandBuffer cmd = VK_NULL_HANDLE); @@ -75,11 +83,11 @@ namespace Scop { public: DepthImage() = default; - inline void Init(std::uint32_t width, std::uint32_t height, bool is_multisampled = false) + inline void Init(std::uint32_t width, std::uint32_t height, bool is_multisampled = false, std::string_view name = {}) { std::vector candidates = { VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT }; VkFormat format = kvfFindSupportFormatInCandidates(RenderCore::Get().GetDevice(), candidates.data(), candidates.size(), VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); - Image::Init(ImageType::Depth, width, height, format, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, is_multisampled); + Image::Init(ImageType::Depth, width, height, format, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, is_multisampled, std::move(name)); Image::TransitionLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); Image::CreateImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_DEPTH_BIT); } @@ -90,13 +98,13 @@ namespace Scop { public: Texture() = default; - Texture(CPUBuffer pixels, std::uint32_t width, std::uint32_t height, VkFormat format = VK_FORMAT_R8G8B8A8_SRGB, bool is_multisampled = false) + Texture(CPUBuffer pixels, std::uint32_t width, std::uint32_t height, VkFormat format = VK_FORMAT_R8G8B8A8_SRGB, bool is_multisampled = false, std::string_view name = {}) { - Init(std::move(pixels), width, height, format, is_multisampled); + Init(std::move(pixels), width, height, format, is_multisampled, std::move(name)); } - inline void Init(CPUBuffer pixels, std::uint32_t width, std::uint32_t height, VkFormat format = VK_FORMAT_R8G8B8A8_SRGB, bool is_multisampled = false) + inline void Init(CPUBuffer pixels, std::uint32_t width, std::uint32_t height, VkFormat format = VK_FORMAT_R8G8B8A8_SRGB, bool is_multisampled = false, std::string_view name = {}) { - Image::Init(ImageType::Color, width, height, format, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, is_multisampled); + Image::Init(ImageType::Color, width, height, format, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, is_multisampled, std::move(name)); Image::CreateImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT); Image::CreateSampler(); if(pixels) @@ -126,11 +134,11 @@ namespace Scop { public: CubeTexture() = default; - CubeTexture(CPUBuffer pixels, std::uint32_t width, std::uint32_t height, VkFormat format = VK_FORMAT_R8G8B8A8_SRGB) + CubeTexture(CPUBuffer pixels, std::uint32_t width, std::uint32_t height, VkFormat format = VK_FORMAT_R8G8B8A8_SRGB, std::string_view name = {}) { - Init(std::move(pixels), width, height, format); + Init(std::move(pixels), width, height, format, std::move(name)); } - void Init(CPUBuffer pixels, std::uint32_t width, std::uint32_t height, VkFormat format = VK_FORMAT_R8G8B8A8_SRGB); + void Init(CPUBuffer pixels, std::uint32_t width, std::uint32_t height, VkFormat format = VK_FORMAT_R8G8B8A8_SRGB, std::string_view name = {}); ~CubeTexture() override { Destroy(); } }; } diff --git a/ScopEngine/Runtime/Includes/Renderer/Pipelines/Graphics.h b/ScopEngine/Runtime/Includes/Renderer/Pipelines/Graphics.h index da54644..989f680 100644 --- a/ScopEngine/Runtime/Includes/Renderer/Pipelines/Graphics.h +++ b/ScopEngine/Runtime/Includes/Renderer/Pipelines/Graphics.h @@ -20,6 +20,7 @@ namespace Scop std::vector> color_attachments; NonOwningPtr depth = nullptr; NonOwningPtr renderer = nullptr; + std::string name = {}; VkCullModeFlagBits culling = VK_CULL_MODE_FRONT_BIT; VkPolygonMode mode = VK_POLYGON_MODE_FILL; bool no_vertex_inputs = false; @@ -41,7 +42,7 @@ namespace Scop [[nodiscard]] inline VkPipelineLayout GetPipelineLayout() const override { return m_pipeline_layout; } [[nodiscard]] inline VkPipelineBindPoint GetPipelineBindPoint() const override { return VK_PIPELINE_BIND_POINT_GRAPHICS; } - ~GraphicPipeline() = default; + inline ~GraphicPipeline() noexcept { Destroy(); } private: void CreateFramebuffers(const std::vector>& render_targets, bool clear_attachments); @@ -51,6 +52,7 @@ namespace Scop bool BindPipeline(VkCommandBuffer) noexcept override { return false; }; private: + std::string m_name; std::vector> m_attachments; std::vector m_framebuffers; std::vector m_clears; diff --git a/ScopEngine/Runtime/Sources/Debug/ImGuiRenderer.cpp b/ScopEngine/Runtime/Sources/Debug/ImGuiRenderer.cpp index e7f2fec..611cf0a 100644 --- a/ScopEngine/Runtime/Sources/Debug/ImGuiRenderer.cpp +++ b/ScopEngine/Runtime/Sources/Debug/ImGuiRenderer.cpp @@ -96,12 +96,12 @@ namespace Scop void ImGuiRenderer::Destroy() { RenderCore::Get().WaitDeviceIdle(); - ImGui_ImplVulkan_Shutdown(); - ImGui_ImplSDL2_Shutdown(); - ImGui::DestroyContext(); for(VkFramebuffer fb : m_framebuffers) kvfDestroyFramebuffer(RenderCore::Get().GetDevice(), fb); m_framebuffers.clear(); + ImGui_ImplVulkan_Shutdown(); + ImGui_ImplSDL2_Shutdown(); + ImGui::DestroyContext(); kvfDestroyRenderPass(RenderCore::Get().GetDevice(), m_renderpass); RenderCore::Get().vkDestroyDescriptorPool(RenderCore::Get().GetDevice(), m_pool, nullptr); } @@ -116,7 +116,6 @@ namespace Scop void ImGuiRenderer::DisplayRenderStatistics() { - static std::array gpu_types_string = { "Other", "Integrated", diff --git a/ScopEngine/Runtime/Sources/Graphics/Loaders/BMP.cpp b/ScopEngine/Runtime/Sources/Graphics/Loaders/BMP.cpp index b368c63..672f816 100644 --- a/ScopEngine/Runtime/Sources/Graphics/Loaders/BMP.cpp +++ b/ScopEngine/Runtime/Sources/Graphics/Loaders/BMP.cpp @@ -39,7 +39,7 @@ namespace Scop buffer.GetData()[i + 2] = data.x; buffer.GetData()[i + 3] = 0xFF; } - Message("BMP Loader : loaded %", path); + Message("BMP Loader: loaded %", path); return buffer; } } diff --git a/ScopEngine/Runtime/Sources/Graphics/Loaders/OBJ.cpp b/ScopEngine/Runtime/Sources/Graphics/Loaders/OBJ.cpp index 92b71b9..60afd7f 100644 --- a/ScopEngine/Runtime/Sources/Graphics/Loaders/OBJ.cpp +++ b/ScopEngine/Runtime/Sources/Graphics/Loaders/OBJ.cpp @@ -11,7 +11,7 @@ namespace Scop { if(!std::filesystem::exists(path)) { - Error("OBJ loader : OBJ file does not exists; %", path); + Error("OBJ loader: OBJ file does not exists; %", path); return std::nullopt; } char line[1024]; @@ -88,7 +88,7 @@ namespace Scop ObjData::FaceList& fl = face; fl.second.push_back(fl.first.size()); } - Message("OBJ Loader : loaded %", path); + Message("OBJ Loader: loaded %", path); return data; } diff --git a/ScopEngine/Runtime/Sources/Graphics/Scene.cpp b/ScopEngine/Runtime/Sources/Graphics/Scene.cpp index 5613789..c5fa6af 100644 --- a/ScopEngine/Runtime/Sources/Graphics/Scene.cpp +++ b/ScopEngine/Runtime/Sources/Graphics/Scene.cpp @@ -72,7 +72,7 @@ namespace Scop if(event.What() == Event::ResizeEventCode) { m_depth.Destroy(); - m_depth.Init(renderer->GetSwapchain().GetSwapchainImages().back().GetWidth(), renderer->GetSwapchain().GetSwapchainImages().back().GetHeight()); + m_depth.Init(renderer->GetSwapchain().GetSwapchainImages().back().GetWidth(), renderer->GetSwapchain().GetSwapchainImages().back().GetHeight(), false, m_name + "_depth"); } if(event.What() == Event::ResizeEventCode || event.What() == Event::SceneHasChangedEventCode) @@ -81,9 +81,9 @@ namespace Scop EventBus::RegisterListener({ functor, m_name + std::to_string(reinterpret_cast(this)) }); auto vertex_shader = RenderCore::Get().GetDefaultVertexShader(); - m_depth.Init(renderer->GetSwapchain().GetSwapchainImages().back().GetWidth(), renderer->GetSwapchain().GetSwapchainImages().back().GetHeight()); + m_depth.Init(renderer->GetSwapchain().GetSwapchainImages().back().GetWidth(), renderer->GetSwapchain().GetSwapchainImages().back().GetHeight(), false, m_name + "_depth"); m_forward.matrices_buffer = std::make_shared(); - m_forward.matrices_buffer->Init(sizeof(ViewerData)); + m_forward.matrices_buffer->Init(sizeof(ViewerData), m_name + "_matrice_buffer"); m_forward.matrices_set = std::make_shared(vertex_shader->GetShaderLayout().set_layouts[0].second, vertex_shader->GetPipelineLayout().set_layouts[0], ShaderType::Vertex); for(std::size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) diff --git a/ScopEngine/Runtime/Sources/Renderer/Buffer.cpp b/ScopEngine/Runtime/Sources/Renderer/Buffer.cpp index 56ca372..ab51f71 100644 --- a/ScopEngine/Runtime/Sources/Renderer/Buffer.cpp +++ b/ScopEngine/Runtime/Sources/Renderer/Buffer.cpp @@ -4,7 +4,7 @@ namespace Scop { - void GPUBuffer::Init(BufferType type, VkDeviceSize size, VkBufferUsageFlags usage, CPUBuffer data) + void GPUBuffer::Init(BufferType type, VkDeviceSize size, VkBufferUsageFlags usage, CPUBuffer data, std::string_view name) { if(type == BufferType::Constant) { @@ -30,7 +30,7 @@ namespace Scop if(type == BufferType::Staging && data.Empty()) Warning("Vulkan: trying to create staging buffer without data (wtf?)"); - CreateBuffer(size, m_usage, m_flags); + CreateBuffer(size, m_usage, m_flags, std::move(name)); if(!data.Empty()) { @@ -41,7 +41,7 @@ namespace Scop PushToGPU(); } - void GPUBuffer::CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties) + void GPUBuffer::CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, std::string_view name) { auto device = RenderCore::Get().GetDevice(); m_buffer = kvfCreateBuffer(device, usage, size); @@ -52,7 +52,33 @@ namespace Scop m_memory = RenderCore::Get().GetAllocator().Allocate(size, mem_requirements.alignment, *FindMemoryType(mem_requirements.memoryTypeBits, properties)); //m_memory = RenderCore::Get().GetAllocator().Allocate(mem_requirements.size, mem_requirements.alignment, *FindMemoryType(mem_requirements.memoryTypeBits, properties)); RenderCore::Get().vkBindBufferMemory(device, m_buffer, m_memory.memory, m_memory.offset); - Message("Vulkan: created buffer"); + + #ifdef SCOP_HAS_DEBUG_UTILS_FUNCTIONS + std::string alloc_name{ name }; + if(usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT) + alloc_name.append("_index_buffer"); + else if(usage & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) + alloc_name.append("_vertex_buffer"); + else if(usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) + alloc_name.append("_uniform_buffer"); + else + alloc_name.append("_buffer"); + if(m_flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) + alloc_name.append("_gpu"); + m_name = name; + + VkDebugUtilsObjectNameInfoEXT name_info{}; + name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + name_info.objectType = VK_OBJECT_TYPE_BUFFER; + name_info.objectHandle = reinterpret_cast(m_buffer); + name_info.pObjectName = m_name.c_str(); + RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info); + + Message("Vulkan: % buffer created", m_name); + #else + Message("Vulkan: buffer created"); + #endif + s_buffer_count++; } @@ -85,7 +111,7 @@ namespace Scop GPUBuffer new_buffer; new_buffer.m_usage = (this->m_usage & 0xFFFFFFFC) | VK_BUFFER_USAGE_TRANSFER_DST_BIT; new_buffer.m_flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; - new_buffer.CreateBuffer(m_memory.size, new_buffer.m_usage, new_buffer.m_flags); + new_buffer.CreateBuffer(m_memory.size, new_buffer.m_usage, new_buffer.m_flags, m_name); if(new_buffer.CopyFrom(*this)) Swap(new_buffer); @@ -150,11 +176,11 @@ namespace Scop staging.Destroy(); } - void UniformBuffer::Init(std::uint32_t size) + void UniformBuffer::Init(std::uint32_t size, std::string_view name) { for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { - m_buffers[i].Init(BufferType::HighDynamic, size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, {}); + m_buffers[i].Init(BufferType::HighDynamic, size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, {}, name); m_maps[i] = m_buffers[i].GetMap(); if(m_maps[i] == nullptr) FatalError("Vulkan: unable to map a uniform buffer"); diff --git a/ScopEngine/Runtime/Sources/Renderer/Image.cpp b/ScopEngine/Runtime/Sources/Renderer/Image.cpp index 03db6cc..f66f27f 100644 --- a/ScopEngine/Runtime/Sources/Renderer/Image.cpp +++ b/ScopEngine/Runtime/Sources/Renderer/Image.cpp @@ -4,7 +4,7 @@ namespace Scop { - void Image::Init(ImageType type, std::uint32_t width, std::uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, bool is_multisampled) + void Image::Init(ImageType type, std::uint32_t width, std::uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, bool is_multisampled, std::string_view name) { m_type = type; m_width = width; @@ -49,7 +49,19 @@ namespace Scop m_memory = RenderCore::Get().GetAllocator().Allocate(mem_requirements.size, mem_requirements.alignment, *FindMemoryType(mem_requirements.memoryTypeBits, properties), true); RenderCore::Get().vkBindImageMemory(RenderCore::Get().GetDevice(), m_image, m_memory.memory, 0); - Message("Vulkan: image created"); + + #ifdef SCOP_HAS_DEBUG_UTILS_FUNCTIONS + VkDebugUtilsObjectNameInfoEXT name_info{}; + name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + name_info.objectType = VK_OBJECT_TYPE_IMAGE; + name_info.objectHandle = reinterpret_cast(m_image); + name_info.pObjectName = name.data(); + RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info); + Message("Vulkan: % image created", name); + #else + Message("Vulkan: image created"); + #endif + s_image_count++; } @@ -68,17 +80,16 @@ namespace Scop if(new_layout == m_layout) return; bool is_single_time_cmd_buffer = (cmd == VK_NULL_HANDLE); - if(is_single_time_cmd_buffer) - cmd = kvfCreateCommandBuffer(RenderCore::Get().GetDevice()); KvfImageType kvf_type = KVF_IMAGE_OTHER; switch(m_type) { case ImageType::Color: kvf_type = KVF_IMAGE_COLOR; break; case ImageType::Depth: kvf_type = KVF_IMAGE_DEPTH; break; case ImageType::Cube: kvf_type = KVF_IMAGE_CUBE; break; - default: break; } + if(is_single_time_cmd_buffer) + cmd = kvfCreateCommandBuffer(RenderCore::Get().GetDevice()); kvfTransitionImageLayout(RenderCore::Get().GetDevice(), m_image, kvf_type, cmd, m_format, m_layout, new_layout, is_single_time_cmd_buffer); if(is_single_time_cmd_buffer) kvfDestroyCommandBuffer(RenderCore::Get().GetDevice(), cmd); @@ -128,6 +139,8 @@ namespace Scop void Image::Destroy() noexcept { + if(m_image == VK_NULL_HANDLE && m_image_view == VK_NULL_HANDLE && m_sampler == VK_NULL_HANDLE) + return; RenderCore::Get().WaitDeviceIdle(); DestroySampler(); DestroyImageView(); @@ -140,10 +153,18 @@ namespace Scop } Message("Vulkan: image destroyed"); m_image = VK_NULL_HANDLE; + m_memory = NULL_MEMORY_BLOCK; + m_image = VK_NULL_HANDLE; + m_image_view = VK_NULL_HANDLE; + m_sampler = VK_NULL_HANDLE; + m_layout = VK_IMAGE_LAYOUT_UNDEFINED; + m_width = 0; + m_height = 0; + m_is_multisampled = false; s_image_count--; } - void CubeTexture::Init(CPUBuffer pixels, std::uint32_t width, std::uint32_t height, VkFormat format) + void CubeTexture::Init(CPUBuffer pixels, std::uint32_t width, std::uint32_t height, VkFormat format, std::string_view name) { if(!pixels) FatalError("Vulkan: a cubemap cannot be created without pixels data"); @@ -198,7 +219,7 @@ namespace Scop pointer_offset += current_size; } - Image::Init(ImageType::Cube, face_width, face_height, format, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + Image::Init(ImageType::Cube, face_width, face_height, format, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, false, std::move(name)); Image::CreateImageView(VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_ASPECT_COLOR_BIT, 6); Image::CreateSampler(); diff --git a/ScopEngine/Runtime/Sources/Renderer/Pipelines/Graphics.cpp b/ScopEngine/Runtime/Sources/Renderer/Pipelines/Graphics.cpp index 2d2d284..a16f5f7 100644 --- a/ScopEngine/Runtime/Sources/Renderer/Pipelines/Graphics.cpp +++ b/ScopEngine/Runtime/Sources/Renderer/Pipelines/Graphics.cpp @@ -18,6 +18,9 @@ namespace Scop p_renderer = descriptor.renderer; p_depth = descriptor.depth; + m_name = descriptor.name; + std::cout << m_name << std::endl; + std::vector push_constants; std::vector set_layouts; push_constants.insert(push_constants.end(), p_vertex_shader->GetPipelineLayout().push_constants.begin(), p_vertex_shader->GetPipelineLayout().push_constants.end()); @@ -58,8 +61,37 @@ namespace Scop } m_pipeline = kvfCreateGraphicsPipeline(RenderCore::Get().GetDevice(), VK_NULL_HANDLE, m_pipeline_layout, builder, m_renderpass); - Message("Vulkan: graphics pipeline created"); kvfDestroyGPipelineBuilder(builder); + + #ifdef SCOP_HAS_DEBUG_UTILS_FUNCTIONS + VkDebugUtilsObjectNameInfoEXT name_info{}; + name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + name_info.objectType = VK_OBJECT_TYPE_PIPELINE; + name_info.objectHandle = reinterpret_cast(m_pipeline); + name_info.pObjectName = descriptor.name.data(); + RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info); + + name_info.objectType = VK_OBJECT_TYPE_RENDER_PASS; + name_info.objectHandle = reinterpret_cast(m_renderpass); + RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info); + + name_info.objectType = VK_OBJECT_TYPE_SHADER_MODULE; + name_info.objectHandle = reinterpret_cast(p_vertex_shader->GetShaderModule()); + RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info); + + name_info.objectHandle = reinterpret_cast(p_fragment_shader->GetShaderModule()); + RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info); + + name_info.objectType = VK_OBJECT_TYPE_FRAMEBUFFER; + for(VkFramebuffer fb : m_framebuffers) + { + name_info.objectHandle = reinterpret_cast(fb); + RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info); + } + Message("Vulkan: % graphics pipeline created", descriptor.name); + #else + Message("Vulkan: graphics pipeline created"); + #endif } bool GraphicPipeline::BindPipeline(VkCommandBuffer command_buffer, std::size_t framebuffer_index, std::array clear) noexcept @@ -106,23 +138,33 @@ namespace Scop void GraphicPipeline::Destroy() noexcept { + if(m_pipeline == VK_NULL_HANDLE) + return; + std::cout << m_name << std::endl; RenderCore::Get().WaitDeviceIdle(); - p_vertex_shader.reset(); - p_fragment_shader.reset(); + for(auto& fb : m_framebuffers) { kvfDestroyFramebuffer(RenderCore::Get().GetDevice(), fb); Message("Vulkan: framebuffer destroyed"); } - m_framebuffers.clear(); + kvfDestroyPipelineLayout(RenderCore::Get().GetDevice(), m_pipeline_layout); - m_pipeline_layout = VK_NULL_HANDLE; Message("Vulkan: graphics pipeline layout destroyed"); kvfDestroyRenderPass(RenderCore::Get().GetDevice(), m_renderpass); - m_renderpass = VK_NULL_HANDLE; Message("Vulkan: renderpass destroyed"); kvfDestroyPipeline(RenderCore::Get().GetDevice(), m_pipeline); + + p_vertex_shader.reset(); + p_fragment_shader.reset(); + m_attachments.clear(); + m_framebuffers.clear(); + m_clears.clear(); + m_renderpass = VK_NULL_HANDLE; m_pipeline = VK_NULL_HANDLE; + m_pipeline_layout = VK_NULL_HANDLE; + p_renderer = nullptr; + p_depth = nullptr; Message("Vulkan: graphics pipeline destroyed"); } @@ -177,10 +219,6 @@ namespace Scop p_depth->TransitionLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, cmd); for(NonOwningPtr image : m_attachments) - { - if(!image->IsInit()) - continue; image->TransitionLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, cmd); - } } } diff --git a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/2DPass.cpp b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/2DPass.cpp index aac7118..4d96b54 100644 --- a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/2DPass.cpp +++ b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/2DPass.cpp @@ -71,6 +71,7 @@ namespace Scop pipeline_descriptor.color_attachments = { &render_target }; pipeline_descriptor.culling = VK_CULL_MODE_NONE; pipeline_descriptor.clear_color_attachments = false; + pipeline_descriptor.name = "2D_pass_pipeline"; m_pipeline.Init(pipeline_descriptor); } diff --git a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/FinalPass.cpp b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/FinalPass.cpp index c4b654c..80c72d9 100644 --- a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/FinalPass.cpp +++ b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/FinalPass.cpp @@ -44,6 +44,7 @@ namespace Scop pipeline_descriptor.renderer = &renderer; pipeline_descriptor.culling = VK_CULL_MODE_NONE; pipeline_descriptor.no_vertex_inputs = true; + pipeline_descriptor.name = "final_pass_pipeline"; m_pipeline.Init(pipeline_descriptor); } diff --git a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/ForwardPass.cpp b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/ForwardPass.cpp index 7bc5873..e5e7c84 100644 --- a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/ForwardPass.cpp +++ b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/ForwardPass.cpp @@ -28,6 +28,7 @@ namespace Scop if(scene.GetForwardData().wireframe) pipeline_descriptor.mode = VK_POLYGON_MODE_LINE; pipeline_descriptor.clear_color_attachments = false; + pipeline_descriptor.name = "forward_pass_pipeline"; pipeline.Init(pipeline_descriptor); } diff --git a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/Passes.cpp b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/Passes.cpp index 830a4df..0d00585 100644 --- a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/Passes.cpp +++ b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/Passes.cpp @@ -23,11 +23,12 @@ namespace Scop if(!m_main_render_texture.IsInit()) { auto extent = kvfGetSwapchainImagesSize(renderer.GetSwapchain().Get()); - m_main_render_texture.Init({}, extent.width, extent.height, VK_FORMAT_R8G8B8A8_UNORM); + m_main_render_texture.Init({}, extent.width, extent.height, VK_FORMAT_R8G8B8A8_UNORM, false, "scop_main_render_texture"); } - m_main_render_texture.Clear(renderer.GetActiveCommandBuffer(), Vec4f{ 0.0f, 0.0f, 0.0f, 1.0f }); scene.GetDepth().Clear(renderer.GetActiveCommandBuffer(), {}); + m_main_render_texture.Clear(renderer.GetActiveCommandBuffer(), Vec4f{ 0.0f, 0.0f, 0.0f, 1.0f }); + m_main_render_texture.TransitionLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, renderer.GetActiveCommandBuffer()); if(scene.GetDescription().render_3D_enabled) m_forward.Pass(scene, renderer, m_main_render_texture); diff --git a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/SkyboxPass.cpp b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/SkyboxPass.cpp index 167a2fb..2183577 100644 --- a/ScopEngine/Runtime/Sources/Renderer/RenderPasses/SkyboxPass.cpp +++ b/ScopEngine/Runtime/Sources/Renderer/RenderPasses/SkyboxPass.cpp @@ -58,6 +58,7 @@ namespace Scop pipeline_descriptor.culling = VK_CULL_MODE_NONE; pipeline_descriptor.depth_test_equal = true; pipeline_descriptor.clear_color_attachments = false; + pipeline_descriptor.name = "skybox_pass_pipeline"; m_pipeline.Init(pipeline_descriptor); } diff --git a/ScopEngine/Runtime/Sources/Renderer/Swapchain.cpp b/ScopEngine/Runtime/Sources/Renderer/Swapchain.cpp index b1024a4..e6335cf 100644 --- a/ScopEngine/Runtime/Sources/Renderer/Swapchain.cpp +++ b/ScopEngine/Runtime/Sources/Renderer/Swapchain.cpp @@ -240,7 +240,7 @@ namespace Scop VkFormat format = kvfGetSwapchainImagesFormat(m_swapchain); for(std::size_t i = 0; i < m_images_count; i++) { - m_swapchain_images[i].Init(tmp[i], format, extent.width, extent.height, VK_IMAGE_LAYOUT_UNDEFINED); + m_swapchain_images[i].Init(tmp[i], format, extent.width, extent.height, VK_IMAGE_LAYOUT_UNDEFINED, std::string{ "swapchain_" + std::to_string(i) }); m_swapchain_images[i].TransitionLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, cmd); m_swapchain_images[i].CreateImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT); }