vkCmdBlitImage中的分段错误

时间:2016-05-05 19:49:29

标签: nvidia vulkan

vkCmdBlitImage中存在分段错误。根据Valgrind的说法,这是一个大小为8的无效读取,地址为0x48。禁用图层无法解决问题。

使用的驱动程序是Nvidia Linux驱动程序版本364.19。 GPU是GeForce GTX 970。

相关代码:

VkImageCreateInfo img_info;
img_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
img_info.pNext = NULL;
img_info.flags = 0;
img_info.imageType = VK_IMAGE_TYPE_2D;
img_info.format = VK_FORMAT_R8G8B8A8_UNORM;
img_info.extent = (VkExtent3D){info.width, info.height, 1};
img_info.mipLevels = 1;
img_info.arrayLayers = 1;
img_info.samples = VK_SAMPLE_COUNT_1_BIT;
img_info.tiling = VK_IMAGE_TILING_LINEAR;
img_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
img_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
img_info.queueFamilyIndexCount = 0;
img_info.pQueueFamilyIndices = NULL;
img_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;

VkImage src_image;
VKR(vkCreateImage(info.device, &img_info, NULL, &src_image));

VkMemoryRequirements src_req;
vkGetImageMemoryRequirements(info.device, src_image, &src_req);
VkDeviceMemory src_mem = create_memory(info.physical_device, info.device,
                                       src_req.memoryTypeBits, src_req.size,
                                       true); //The true makes it create host-visible memory.

vkBindImageMemory(info.device, src_image, src_mem, 0);

VkImageSubresource src_subres;
src_subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
src_subres.mipLevel = 0;
src_subres.arrayLayer = 0;

VkSubresourceLayout src_subres_layout;
vkGetImageSubresourceLayout(info.device, src_image, &src_subres, &src_subres_layout);

uint8_t* src_data = NULL;
VKR(vkMapMemory(info.device, src_mem, src_subres_layout.offset, src_subres_layout.rowPitch*info.height, 0, (void**)&src_data));

//Code that initialized src_data

VkMappedMemoryRange range;
range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
range.pNext = NULL;
range.memory = src_mem;
range.offset = src_subres_layout.offset;
range.size = src_subres_layout.rowPitch * info.height;
VKR(vkFlushMappedMemoryRanges(info.device, 1, &range));
vkUnmapMemory(info.device, src_mem);

VkCommandBufferAllocateInfo alloc_info;
alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
alloc_info.pNext = NULL;
alloc_info.commandPool = info.cmd_pool;
alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
alloc_info.commandBufferCount = 1;
VkCommandBuffer cmd_buf;
VKR(vkAllocateCommandBuffers(info.device, &alloc_info, &cmd_buf));

VkCommandBufferBeginInfo begin_cmd_buf_info;
begin_cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
begin_cmd_buf_info.pNext = NULL;
begin_cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
begin_cmd_buf_info.pInheritanceInfo = NULL;
vkBeginCommandBuffer(cmd_buf, &begin_cmd_buf_info);

image_barrier(VK_IMAGE_ASPECT_COLOR_BIT, cmd_buf, VK_ACCESS_HOST_WRITE_BIT,
              VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_PREINITIALIZED,
              VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_PIPELINE_STAGE_HOST_BIT,
              VK_PIPELINE_STAGE_TRANSFER_BIT, src_image);

image_barrier(VK_IMAGE_ASPECT_COLOR_BIT, cmd_buf, info.dst_img_access,
              VK_ACCESS_TRANSFER_WRITE_BIT, info.dst_img_layout,
              VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
              VK_PIPELINE_STAGE_TRANSFER_BIT, info.dst_image);

VkImageBlit region;
region.srcSubresource = (VkImageSubresourceLayers){VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
region.srcOffsets[0] = (VkOffset3D){0, 0, 0};
region.srcOffsets[1] = (VkOffset3D){info.width, info.height, 1};
region.dstSubresource = (VkImageSubresourceLayers){VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
region.dstOffsets[0] = (VkOffset3D){0, 0, 0};
region.dstOffsets[1] = (VkOffset3D){info.width, info.height, 1};
vkCmdBlitImage(cmd_buf, src_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, info.dst_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region, VK_FILTER_NEAREST);

vkEndCommandBuffer(cmd_buf);

其余代码可在https://gitlab.com/pendingchaos/WIP29/tree/00f348f2ef588e5f724fcb1f695e7692128cac4c/src找到。

可以在http://pastebin.com/JaHqCy98找到vulkaninfo的输出。

1 个答案:

答案 0 :(得分:0)

你的同步似乎不适合jorb。它们会丢弃您的预初始化图像并且不进行同步(由于dst = BOTTOM)。

让我把你的计算要求很好的4x4图像处理组合起来:

image_barrier( VK_IMAGE_ASPECT_COLOR_BIT, cmd_buf,
               VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
               VK_IMAGE_LAYOUT_PREINITIALIZED, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 
               VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
               src_image);

image_barrier( VK_IMAGE_ASPECT_COLOR_BIT, cmd_buf,
               info.dst_img_access, VK_ACCESS_TRANSFER_WRITE_BIT,
               info.dst_img_layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
               VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
               info.dst_image);

顺便说一句:

  1. amount <{1}} <{1}} <{1}} <{1}} <{1}}
  2. VkDeviceSizesize_tcreateMemory()返回,也许应该在您的vkBindImageMemory()
  3. 如果您重写图像的整个方面,可以使用vkBeginCommandBuffer()丢弃旧数据(效率更高!)
相关问题