中存在分段错误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, ®ion, VK_FILTER_NEAREST);
vkEndCommandBuffer(cmd_buf);
其余代码可在https://gitlab.com/pendingchaos/WIP29/tree/00f348f2ef588e5f724fcb1f695e7692128cac4c/src找到。
减少 vulkaninfo 的输出可以在http://pastebin.com/JaHqCy98找到。