Vulkan verbraucht immer mehr GedächtnisC++

Programme in C++. Entwicklerforum
Anonymous
 Vulkan verbraucht immer mehr Gedächtnis

Post by Anonymous »

Ich versuche derzeit, das Vulkan-Tutorial-Programm in einen Renderer für meine Game-Engine zu modifizieren, stieß jedoch auf Probleme, bei denen mein Renderer im Laufe der Zeit langsam eine immer größere Menge an RAM verbraucht, insbesondere wenn ich Tausende von Meshes (Tausende von Meshes ( Sie sind alle für den gleichen Netz für den Moment).const int MAX_FRAMES_IN_FLIGHT = 2;

void VulkanRenderer::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) {
VkCommandBufferBeginInfo beginInfo = {};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;

VkResult result = vkBeginCommandBuffer(commandBuffer, &beginInfo);

if (result != VK_SUCCESS) {
throw std::runtime_error("Failed to begin recording command buffer!");
}

VkRenderPassBeginInfo renderPassInfo = {};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassInfo.renderPass = app.renderPass;
renderPassInfo.framebuffer = app.swapChainFramebuffers[imageIndex];
renderPassInfo.renderArea.offset = { 0, 0 };
renderPassInfo.renderArea.extent = app.swapChainExtent;

std::array clearValues = {};
clearValues[0].color = { { 0.0f, 0.0f, 0.0f, 1.0f } };
clearValues[1].depthStencil = { 1.0f, 0 };

renderPassInfo.clearValueCount = static_cast(clearValues.size());
renderPassInfo.pClearValues = clearValues.data();

vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);

vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, app.graphicsPipeline);

// Bind the global UBO descriptor set (set 0) for view/projection
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
app.pipelineLayout, 0, 1, &app.globalDescriptorSets[imageIndex],
0, nullptr);

// Iterate over all objects with a MeshComponent and Transform
// This is basically a wrapper for entt's registry.view() function
ObjectManager::Instance().forEachObjectWithComponents([&](MeshComponent& meshComp, Transform& transform) {
// Retrieve (or create) the mesh buffer. (Assumes that AssetManager::meshCache contains a Mesh for meshComp.uuid.)
Mesh& mesh = AssetManager::Instance().meshCache[meshComp.uuid];
VulkanMeshBuffer* meshBuffer = CreateMeshBuffer(meshComp.uuid, mesh);

// Bind vertex and index buffers
VkBuffer vertexBuffers[] = { meshBuffer->vertexBuffer };
VkDeviceSize offsets[] = { 0 };
vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets);
vkCmdBindIndexBuffer(commandBuffer, meshBuffer->indexBuffer, 0, VK_INDEX_TYPE_UINT32);

// Retrieve texture resources for this object’s texture and bind them (set 1)
TextureResource* texRes = getTextureResource(meshComp.TextureUUID);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
app.pipelineLayout, 1, 1, &texRes->descriptorSet,
0, nullptr);

// Compute the model matrix from the Transform component:
glm::mat4 model = glm::translate(glm::mat4(1.0f), transform.position);
model = glm::rotate(model, transform.rotation.x, glm::vec3(1, 0, 0));
model = glm::rotate(model, transform.rotation.y, glm::vec3(0, 1, 0));
model = glm::rotate(model, transform.rotation.z, glm::vec3(0, 0, 1));
model = glm::scale(model, transform.scale);

// Push the model matrix as a push constant (the range was set in the pipeline layout)
vkCmdPushConstants(commandBuffer, app.pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::mat4), &model);

// Issue the draw call (using the index count from the mesh)
vkCmdDrawIndexed(commandBuffer, static_cast(mesh.indices.size()), 1, 0, 0, 0);
});

vkCmdEndRenderPass(commandBuffer);

result = vkEndCommandBuffer(commandBuffer);

if (result != VK_SUCCESS) {
throw VulkanError("Failed to record command buffer!", result);
}
}

void VulkanRenderer::updateUniformBuffer(uint32_t currentImage) {
GlobalUBO ubo = {};
ubo.view = glm::lookAt(glm::vec3(10.0f, 10.0f, 10.0f),
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f));
ubo.proj = glm::perspective(glm::radians(45.0f),
app.swapChainExtent.width / (float)app.swapChainExtent.height,
0.001f, 1000.0f);
ubo.proj[1][1] *= -1; // Flip Y-axis for Vulkan

void* data;
vkMapMemory(app.device, app.uniformBuffersMemory[currentImage], 0, sizeof(ubo), 0, &data);
memcpy(data, &ubo, sizeof(ubo));
vkUnmapMemory(app.device, app.uniformBuffersMemory[currentImage]);
}

void VulkanRenderer::drawFrame() {
vkWaitForFences(app.device, 1, &app.inFlightFences[app.currentFrame], VK_TRUE, UINT64_MAX);
vkResetFences(app.device, 1, &app.inFlightFences[app.currentFrame]);

uint32_t imageIndex;
vkAcquireNextImageKHR(app.device, app.swapChain, UINT64_MAX, app.imageAvailableSemaphores[app.currentFrame], VK_NULL_HANDLE, &imageIndex);

// Update the uniform buffer for the current image
updateUniformBuffer(imageIndex);

// Check if a previous frame is still using this image
if (app.imagesInFlight[imageIndex] != VK_NULL_HANDLE) {
vkWaitForFences(app.device, 1, &app.imagesInFlight[imageIndex], VK_TRUE, UINT64_MAX);
}

// Mark the image as now being in use by this frame
app.imagesInFlight[imageIndex] = app.inFlightFences[app.currentFrame];

// Re-record the command buffer for this frame.
vkResetCommandBuffer(app.commandBuffers[imageIndex], 0);
recordCommandBuffer(app.commandBuffers[imageIndex], imageIndex);

VkSubmitInfo submitInfo = {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;

VkSemaphore waitSemaphores[] = { app.imageAvailableSemaphores[app.currentFrame] };
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = waitSemaphores;
submitInfo.pWaitDstStageMask = waitStages;

submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &app.commandBuffers[imageIndex];

VkSemaphore signalSemaphores[] = { app.renderFinishedSemaphores[app.currentFrame] };
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = signalSemaphores;

if (vkQueueSubmit(app.graphicsQueue, 1, &submitInfo, app.inFlightFences[app.currentFrame]) != VK_SUCCESS) {
throw std::runtime_error("Failed to submit draw command buffer!");
}

VkPresentInfoKHR presentInfo = {};
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.waitSemaphoreCount = 1;
presentInfo.pWaitSemaphores = signalSemaphores;

VkSwapchainKHR swapChains[] = { app.swapChain };
presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = swapChains;
presentInfo.pImageIndices = &imageIndex;

VkResult result = vkQueuePresentKHR(app.presentQueue, &presentInfo);

if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || app.framebufferResized) {
app.framebufferResized = false; // Reset the resize flag
recreateSwapChain(); // Recreate the swap chain when necessary
}
else if (result != VK_SUCCESS) {
throw std::runtime_error("Failed to present swap chain image!");
}

app.currentFrame = (app.currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
}

void VulkanRenderer::Update()
{
last_frame_elapsed += Engine::Instance().GetDeltaTime();

if (last_frame_elapsed >= frame_time) {
drawFrame();
vkDeviceWaitIdle(app.device); // Wait until GPU finishes rendering
last_frame_elapsed = 0.0;
}
}
< /code>
Habe ich irgendwo durcheinander gebracht? Weil ich nicht genau herausfinden kann, welcher Teil meines Programms das Gedächtnis verschlingt.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post