微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Vulkan:将一个 VkBuffer 一分为二时内存使用量大幅增加

如何解决Vulkan:将一个 VkBuffer 一分为二时内存使用量大幅增加

设置

我按照 this tutorial 设置了 vulkan 应用程序。这是它的外观:

enter image description here

此阶段的源代码可用 here

我想做什么

我正在尝试将两种不同的纹理应用于两个方块。为此,我将两个方块拆分为单独的 VkBuffers(一个顶点缓冲区和一个索引缓冲区)。

出了什么问题

在拆分之前,内存使用量在 120MB 左右浮动。但之后,使用量约为 230MB。我认为这不应该发生,我正在努力找出原因。

我做了什么

创建缓冲区(以顶点缓冲区为例)。

  vertexBuffers.resize(vertices.size());
  vertexBufferAllocations.resize(vertices.size());
  for (size_t i = 0; i != vertices.size(); i++) {
    VkDeviceSize bufferSize = sizeof(vertices[i][0]) * vertices[i].size();

    VkBuffer stagingBuffer;
    VmaAllocation stagingBufferAllocation;
    createBuffer(bufferSize,VK_BUFFER_USAGE_TRANSFER_SRC_BIT,VMA_MEMORY_USAGE_cpu_ONLY,stagingBuffer,stagingBufferAllocation);

    void *data;
    vmaMapMemory(allocator,stagingBufferAllocation,&data);
    memcpy(data,vertices[i].data(),bufferSize);
    vmaUnmapMemory(allocator,stagingBufferAllocation);

    createBuffer(bufferSize,VK_BUFFER_USAGE_TRANSFER_DST_BIT |
                     VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,VMA_MEMORY_USAGE_GPU_ONLY,vertexBuffers[i],vertexBufferAllocations[i]);
    copyBuffer(stagingBuffer,bufferSize);

    vmaDestroyBuffer(allocator,stagingBufferAllocation);
  }

我正在使用的命令缓冲区(我认为这与内存使用无关,但以防万一):

  if (vkBeginCommandBuffer(commandBuffers[i],&beginInfo) != VK_SUCCESS) {
    throw runtime_error("Failed to begin recording command buffer!");
  }

  array<VkClearValue,2> clearValues{};
  clearValues[0].color = {0.0f,0.0f,1.0f};
  clearValues[1].depthStencil = {1.0f,0};
  VkRenderPassBeginInfo renderPassBeginInfo{
      .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,.renderPass = renderPass,.framebuffer = swapChainFramebuffers[i],.renderArea = {.offset = {0,0},.extent = swapChainExtent},.clearValueCount = static_cast<uint32_t>(clearValues.size()),.pClearValues = clearValues.data(),};
  vkCmdBeginRenderPass(commandBuffers[i],&renderPassBeginInfo,VK_SUBPASS_CONTENTS_INLINE);
  vkCmdBindPipeline(commandBuffers[i],VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline);

  vkCmdBindDescriptorSets(commandBuffers[i],pipelineLayout,1,&descriptorSets[i],nullptr);
  for (size_t j = 0; j != vertices.size(); j++) {
    VkBuffer vertexBufferArray[] = {vertexBuffers[j]};
    VkDeviceSize offsets[] = {0};
    vkCmdBindVertexBuffers(commandBuffers[i],vertexBufferArray,offsets);
    vkCmdBindindexBuffer(commandBuffers[i],indexBuffers[j],VK_INDEX_TYPE_UINT16);
    vkCmdDrawIndexed(commandBuffers[i],static_cast<uint32_t>(indices[j].size()),0);
  }

  vkCmdEndRenderPass(commandBuffers[i]);
  if (vkEndCommandBuffer(commandBuffers[i]) != VK_SUCCESS) {
    throw runtime_error("Failed to record command buffer!");
  }

提前致谢!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。