Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在Vulkan Api上使用暂存缓冲区解决网格损坏_C++_Vulkan - Fatal编程技术网

C++ 如何在Vulkan Api上使用暂存缓冲区解决网格损坏

C++ 如何在Vulkan Api上使用暂存缓冲区解决网格损坏,c++,vulkan,C++,Vulkan,我发现我的代码中有一个bug,在某些情况下使用暂存缓冲区会导致网格数据损坏。我有: 临时网格数据 具有一定大小的暂存缓冲区,由命令缓冲区和memcpy同时使用,但一次不使用相同的段 缓冲区分配器,提供适当顶点索引缓冲区的一部分,其中网格数据通过vkCmdCopyBuffer从暂存传输。缓冲区包含许多为不同网格指定的线段 当我通过命令buffer和memcpy同时使用staging buffer时,mesh数据写入错误(被覆盖/损坏),甚至严重,可能会导致VK_错误(VK)设备(VK)丢失 “正确

我发现我的代码中有一个bug,在某些情况下使用暂存缓冲区会导致网格数据损坏。我有:

  • 临时网格数据

  • 具有一定大小的暂存缓冲区,由命令缓冲区和memcpy同时使用,但一次不使用相同的段

  • 缓冲区分配器,提供适当顶点索引缓冲区的一部分,其中网格数据通过vkCmdCopyBuffer从暂存传输。缓冲区包含许多为不同网格指定的线段

  • 当我通过命令buffer和memcpy同时使用staging buffer时,mesh数据写入错误(被覆盖/损坏),甚至严重,可能会导致VK_错误(VK)设备(VK)丢失

    “正确的网格”

    “断网”

    [[nodiscard]]静态结果writeMeshBuffer(TransferData&data,GpuMesh&buffer)
    {
    结果;使用名称空间vkw;
    auto&mesh=buffer.source;
    size\u t vSize=mesh.vertexts\u count*mesh.vertext\u size;
    size\t iSize=mesh.index\u计数*mesh.index\u大小;
    大小\u t网格\u大小=vSize+iSize;
    自动暂存偏移量=data.stagingData.buffer\u偏移量未使用(&T);
    //将数据写入暂存缓冲区
    {
    //保证网格大小小于或等于暂存缓冲区大小
    //FIXME false条件以某种方式生成断开的网格
    bool是\u wait\u before=mesh\u size>TransferStagingData::BUFFER\u size-staging\u offset;
    //将正常工作:
    //bool是_wait_before=true;
    if(is_wait_before)//如果我们在暂存缓冲区上需要比未使用的更多的内存
    {
    结果=数据。等待传输();
    如果(结果!=VK_成功)
    返回结果;
    分段偏移量=0;
    }
    uint8_t*pMemory=静态_转换(data.stagingData.pMemory)+暂存偏移量;
    memcpy(pMemory、mesh.vertices.pX、vSize);
    memcpy(pMemory+vSize、mesh.index.pXX、iSize);
    如果(不是之前等待)
    {
    结果=数据。等待传输();
    如果(结果!=VK_成功)
    返回结果;
    }
    }
    //将数据从暂存缓冲区写入网格缓冲区
    {
    auto cmd_cpy_buff=[](CommandBuffer cmd、BufferCopy copy、offset offset、DeviceSizeT size)
    {
    cmd.cmd\u copy\u缓冲区(复制、偏移、大小);
    };
    //SRC DST
    BufferCopy copy={data.stagingData.buffer,buffer.info.buffer};
    偏移量偏移量={staging_offset,buffer.info.region.offset};
    结果=data.transfer.prepare(cmd_cpy_buff,data.transfer.cmd_buffer,copy,offset,mesh_size);
    如果(结果!=VK_成功)
    返回结果;
    data.reset_fence();
    结果=data.transfer.submit({&data.transfer.cmd_buffer,1},{},{},{},data.transferFence);
    如果(结果!=VK_成功)
    返回结果;
    }
    //将使用的偏移量保存到data.stagingData.buffer\u offset\u unused;
    分段偏移=分段偏移==0?网格尺寸:0;
    返回结果;
    }
    
    如果我不能像这样使用暂存缓冲区,为什么

    如果我有错误,idk where。

    问题是

    staging_offset = staging_offset == 0 ? mesh_size : 0;
    
    需要改变

    staging_offset = staging_offset == 0 ? TransferStagingData::BUFFER_SIZE - mesh_size : 0;
    
    更换后,所有部件都能正常工作

    staging_offset = staging_offset == 0 ? TransferStagingData::BUFFER_SIZE - mesh_size : 0;