Memcpy出现访问冲突失败-Vulkan复制到顶点缓冲区

菲格威格

我正在尝试将一些数据传递给Vulkan中的GPU。AFAIK,做到这一点的唯一方法是使用memcpy。这适用于较小的向量,但是对于较大的模型,尝试执行此操作时会遇到访问冲突异常。相同的方法可在同一台机器上的另一种实现中使用。我应该找什么?谢谢

这是代码

void VulkanAllocator::createVertexBuffer(std::vector<HE2_Vertex>* vertices, VkBuffer& vertexBuffer, VkDeviceMemory& vertexBufferMemory)
{
VkDeviceSize bufferSize = sizeof(HE2_Vertex) * vertices->size();

VkBuffer stagingBuffer;
VkDeviceMemory stagingBufferMemory;

createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, stagingBuffer, stagingBufferMemory);

VkMemoryRequirements memReqs;

vkGetBufferMemoryRequirements(vdi->device, stagingBuffer, &memReqs);


void* data;

if (vkMapMemory(vdi->device, stagingBufferMemory, 0, (size_t)memReqs.size, 0, &data) != VK_SUCCESS)
{
    throw std::exception("Bad Memory map!");
}

memcpy(data, vertices->data(), (size_t)memReqs.size); //Crash after this line


vkUnmapMemory(vdi->device, stagingBufferMemory);

createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
    VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer, vertexBufferMemory);

copyBuffer(stagingBuffer, vertexBuffer, bufferSize);

vkDestroyBuffer(vdi->device, stagingBuffer, nullptr);
vkFreeMemory(vdi->device, stagingBufferMemory, nullptr);
}

和CreateBuffer看起来像这样

void VulkanAllocator::createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory)
{
    VkBufferCreateInfo bufferInfo = {};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = size;
bufferInfo.usage = usage;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

if (vkCreateBuffer(vdi->device, &bufferInfo, nullptr, &buffer) != VK_SUCCESS)
{
    throw std::runtime_error("Unable to create vertex buffer");
}

VkMemoryRequirements memRequirements;

vkGetBufferMemoryRequirements(vdi->device, buffer, &memRequirements);

VkMemoryAllocateInfo allocInfo = {};

allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.allocationSize = memRequirements.size;
allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);

if (vkAllocateMemory(vdi->device, &allocInfo, nullptr, &bufferMemory) != VK_SUCCESS)
{
    throw std::runtime_error("failed to allocate vertex buffer memory");
}

vkBindBufferMemory(vdi->device, buffer, bufferMemory, 0);
}

向量是这样创建的(如果您经历过https://vulkan-tutorial.com/,则可能认识到我的重构)。HE2_Model仅包含HE2_Vertexs的向量和uint32_ts的向量我不知道是否相关,但尚未为编写副本构造函数HE2_Vertex

HE2_Model *模型=新的HE2_Model();

//Using tiny_obj_loader to pull in from a file
tinyobj::attrib_t attrib;
std::vector<tinyobj::shape_t> shapes;
std::vector<tinyobj::material_t> materials;

std::string warn, err;

if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, filename.c_str()))
{
    throw std::runtime_error("Couldn't load model!");
}

std::unordered_map<HE2_Vertex, uint32_t> uniqueVertices = { };

for (const auto& shape : shapes)
{
    for (const auto& index : shape.mesh.indices)
    {
        HE2_Vertex vertex = {};

        vertex.pos = {
            attrib.vertices[3 * index.vertex_index + 0],
            attrib.vertices[3 * index.vertex_index + 1],
            attrib.vertices[3 * index.vertex_index + 2] };


        vertex.texCoord = {
            attrib.texcoords[2 * index.texcoord_index + 0],
            1.0f - attrib.texcoords[2 * index.texcoord_index + 1] };

        if (uniqueVertices.count(vertex) == 0)
        {
            uniqueVertices[vertex] = static_cast<uint32_t>(model->vertices.size());
            model->vertices.push_back(vertex);
        }

        model->indices.push_back(uniqueVertices[vertex]);
    }
}


HE2_Instance::renderBackend->onAddModel(model);

return model;
菲格威格

足够令人恼火的是,此问题通过重建得以解决。我在一个Visual Studio解决方案中有多个项目,而我只需要学习不依赖项目依赖项,那么我始终需要处理的内存错误和异常的第一件事就是重建每个项目。对于任何具有怪异的访问冲突和行为等的人,最重要的提示-重建重建重建!!!

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Cython如何使用Memcpy从numpy缓冲区复制到C结构?

用于将固定长度的缓冲区复制到结构中的memcpy

使用rdbuf将文件内容复制到缓冲区失败

Vulkan:顶点缓冲区不会发送到顶点着色器

使用顶点缓冲区的直接状态访问

将int复制到字节缓冲区时,为什么要用memcpy / memmove反转数据?

Vulkan-同步访问单个缓冲区

从字符缓冲区复制时,memcpy 返回垃圾数据

在vulkan中同步顶点缓冲区?

Vulkan-顶点缓冲区更新

在GLSL顶点着色器中,您不仅可以访问顶点缓冲区,还可以访问索引缓冲区中顶点的索引吗?

OpenGL-从顶点着色器访问缓冲区中的下3个顶点

使用 memcpy 或 strcpy 在子进程中将 c 字符串从 1 个缓冲区复制到另一个缓冲区似乎不起作用

当我尝试使用 strncpy 将一个数组缓冲区复制到另一个数组缓冲区时,为什么会出现不兼容的指针类型错误?

Vulkan可以用来访问帧缓冲区吗?

顶点着色器如何访问与另一个shaderprogram属性绑定的顶点缓冲区数据?

读取 UNICODE_STRING 缓冲区时的访问冲突

在Vulkan中最通常的更新顶点缓冲区的正确方法

Vulkan 中的动态顶点缓冲区格式设置

memcpy指向char缓冲区的指针

使用 memcpy 处理缓冲区

复制字符串缓冲区时出现分段错误

Vulkan:缓冲区复制期间设备丢失

合并顶点缓冲区

C++缓冲区备份失败

访问协议缓冲区扩展字段

从boost创建的缓冲区访问数据

vim:将缓冲区复制到窗口

如何停止hange复制到粘贴缓冲区?