fixed rookie memory leak in rendertarget_recreate

This commit is contained in:
Ben Kyd
2023-12-30 15:54:46 +00:00
parent 32834878b5
commit 2808defc94
8 changed files with 109 additions and 12 deletions

View File

@@ -31,7 +31,7 @@ else()
target_compile_options(inferno PRIVATE -std=c++20)
target_compile_options(inferno PRIVATE -m64)
if (CMAKE_BUILD_TYPE MATCHES "Debug")
target_compile_options(inferno PRIVATE -O1)
target_compile_options(inferno PRIVATE -O0)
target_compile_options(inferno PRIVATE -Wall)
target_compile_options(inferno PRIVATE -g)
target_compile_options(inferno PRIVATE -D_GLIBCXX_DEBUG)

View File

@@ -117,3 +117,6 @@ inline uint8_t registerModule(std::string name, std::string ANSI)
}
// alias yolo to yo for less typing
namespace yo = yolo;

View File

@@ -6,7 +6,7 @@
namespace inferno::graphics {
// #define VALIDATION_LAYERS_ENABLED 1
#define VALIDATION_LAYERS_ENABLED 1
#ifdef VALIDATION_LAYERS_ENABLED
const std::vector<const char*> VALIDATION_LAYERS = {
"VK_LAYER_KHRONOS_validation",

View File

@@ -4,6 +4,7 @@
#include "device.hpp"
#include "graphics.hpp"
#include "image.hpp"
#include "vkrenderer.hpp"
#include "yolo/yolo.hpp"
#include <vulkan/vulkan_core.h>
@@ -44,7 +45,8 @@ RenderTarget* rendertarget_create(
target->TargetImage = new ImageAttachment();
create_image(device, extent.width, extent.height, format, VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
| VK_IMAGE_USAGE_SAMPLED_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, target->TargetImage->Image,
target->TargetImage->Memory);
@@ -54,6 +56,13 @@ RenderTarget* rendertarget_create(
target->DescriptorSet = ImGui_ImplVulkan_AddTexture(target->Sampler,
target->TargetImage->ImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
// wait for the image to be ready
graphics::renderer_submit_now(
device->RenderContext, [&](VulkanRenderer* re, VkCommandBuffer* cmd) {
transition_image_layout(re->Device, target->TargetImage->Image, format,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
});
if (depth) {
rendertarget_create_depth(target);
}
@@ -105,15 +114,70 @@ void rendertarget_recreate(RenderTarget* target, VkExtent2D extent, VkFormat for
bool doDepth = target->TargetDepth != nullptr;
rendertarget_cleanup(target);
vkDestroyImageView(
target->Device->VulkanDevice, target->TargetImage->ImageView, nullptr);
vkDestroyImage(target->Device->VulkanDevice, target->TargetImage->Image, nullptr);
vkFreeMemory(target->Device->VulkanDevice, target->TargetImage->Memory, nullptr);
if (doDepth) {
vkDestroyImageView(
target->Device->VulkanDevice, target->TargetDepth->ImageView, nullptr);
vkDestroyImage(target->Device->VulkanDevice, target->TargetDepth->Image, nullptr);
vkFreeMemory(target->Device->VulkanDevice, target->TargetDepth->Memory, nullptr);
}
target->Extent = extent;
target->Format = format;
rendertarget_create(target->Device, extent, format, doDepth);
VkSamplerCreateInfo samplerInfo {};
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
samplerInfo.magFilter = VK_FILTER_LINEAR;
samplerInfo.minFilter = VK_FILTER_LINEAR;
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerInfo.anisotropyEnable = VK_FALSE;
samplerInfo.maxAnisotropy = 1.0f;
samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
samplerInfo.unnormalizedCoordinates = VK_FALSE;
samplerInfo.compareEnable = VK_FALSE;
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
samplerInfo.mipLodBias = 0.0f;
samplerInfo.minLod = 0.0f;
samplerInfo.maxLod = 0.0f;
// if (doDepth)
// rendertarget_create_depth(target);
if (vkCreateSampler(
target->Device->VulkanDevice, &samplerInfo, nullptr, &target->Sampler)
!= VK_SUCCESS) {
yolo::error("failed to create texture sampler!");
}
target->TargetImage = new ImageAttachment();
create_image(target->Device, extent.width, extent.height, format,
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
| VK_IMAGE_USAGE_SAMPLED_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, target->TargetImage->Image,
target->TargetImage->Memory);
target->TargetImage->ImageView = create_image_view(
target->Device, target->TargetImage->Image, format, VK_IMAGE_ASPECT_COLOR_BIT);
target->DescriptorSet = ImGui_ImplVulkan_AddTexture(target->Sampler,
target->TargetImage->ImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
// wait for the image to be ready
graphics::renderer_submit_now(
target->Device->RenderContext, [&](VulkanRenderer* re, VkCommandBuffer* cmd) {
transition_image_layout(re->Device, target->TargetImage->Image, format,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
});
if (doDepth) {
rendertarget_create_depth(target);
}
}
DynamicCPUTarget* dynamic_rendertarget_create(
@@ -149,7 +213,8 @@ DynamicCPUTarget* dynamic_rendertarget_create(
// Create VkImage with Undefined
create_image(device, extent.width, extent.height, format, VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
| VK_IMAGE_USAGE_SAMPLED_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, target->Image, target->Memory);
target->ImageView
@@ -191,6 +256,26 @@ void dynamic_rendertarget_update(DynamicCPUTarget* target, void* data, VkExtent2
memcpy(mappedData, data, target->StagingBuffer->Size);
vkUnmapMemory(target->Device->VulkanDevice, target->StagingBuffer->DeviceData);
// No we have the data in the buffer, let's move it to the image
graphics::renderer_submit_now(
target->Device->RenderContext, [&](VulkanRenderer* re, VkCommandBuffer* cmd) {
VkBufferImageCopy region {};
region.bufferOffset = 0;
region.bufferRowLength = 0;
region.bufferImageHeight = 0;
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageOffset = { 0, 0, 0 };
region.imageExtent = { size.width, size.height, 1 };
vkCmdCopyBufferToImage(*cmd, target->StagingBuffer->Handle, target->Image,
VK_IMAGE_LAYOUT_GENERAL, 1, &region);
});
// Sync with Fence
// Transition to whatever we need

View File

@@ -200,6 +200,14 @@ bool renderer_begin_frame(VulkanRenderer* renderer)
void renderer_begin_pass(
VulkanRenderer* renderer, RenderTarget* target, VkRect2D renderArea, bool clear)
{
// Validate that "Image" is valid
if (target == nullptr || target->TargetImage == nullptr) {
yolo::error("Target image is null");
}
// print target details
yo::info("Target: {} {} {}", target->TargetImage->Image, target->TargetImage->Memory,
target->TargetImage->ImageView);
VkImageMemoryBarrier imageMemoryBarrier {};
imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;

View File

@@ -352,7 +352,6 @@ int inferno_run(InfernoApp* app)
}
if (ImGui::Begin("Render")) {
graphics::rayr_prepare(app->RayRenderer);
graphics::rayr_draw(app->RayRenderer);
ImTextureID texture

View File

@@ -38,6 +38,7 @@ PreviewRenderer* preview_create(VulkanRenderer* vkrenderer)
renderer->PreviewRenderTarget = graphics::rendertarget_create(
renderer->Renderer->Device, { 1920, 1080 }, VK_FORMAT_R8G8B8A8_UNORM, true);
yolo::info("Created preview rendertarget");
// bind preview renderer to debugdraw
debug_init(renderer);
@@ -71,10 +72,12 @@ void preview_draw(PreviewRenderer* renderer, scene::Scene* scene)
VkCommandBuffer commandBuffer = *renderer->Renderer->CommandBufferInFlight;
// if changed
if (renderer->HasViewportChanged) {
yolo::info("Resizing preview");
graphics::rendertarget_recreate(renderer->PreviewRenderTarget,
renderer->Viewport.extent, VK_FORMAT_R8G8B8A8_UNORM);
}
yolo::info("Drawing preview");
graphics::renderer_begin_pass(
renderer->Renderer, renderer->PreviewRenderTarget, renderer->Viewport);

View File

@@ -96,9 +96,8 @@ void rayr_draw(RayRenderer* renderer)
#pragma omp parallel for
for (int x = 0; x < renderer->Viewport.extent.width; x++) {
for (int y = 0; y < renderer->Viewport.extent.height; y++) {
renderer->RenderData[y * renderer->Viewport.extent.width + x]
= { 0.0f, 0.0f, 0.0f, 1.0f };
// rays::Ray* ray = startRays.Field[x * renderer->Viewport.extent.height + y];
rays::Ray* ray = startRays.Field[x * renderer->Viewport.extent.height + y];
renderer->RenderData[y * renderer->Viewport.extent.width + x] = glm::vec4(ray->Direction, 1.0);
// rays::HitInfo* closest_hit = nullptr;
//
// for (auto& obj : scene::scene_get_renderables(renderer->Scene)) {