3

にセグメンテーション違反がありvkCmdBlitImageます。Valgrind によると、アドレスが 0x48 のサイズ 8 の無効な読み取りです。レイヤーを無効にしても問題は解決しません。

使用されるドライバーは、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 の出力を切り詰めることができます。

4

1 に答える 1

0

あなたの同期は、この仕事には不適切なようです。事前に初期化されたイメージを破棄し、同期を行いません (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ませVkDeviceSizesize_tcreateMemory()
  2. vkBindImageMemory()vkBeginCommandBuffer()そしてvkEndCommandBuffer()戻り、おそらくあなたの中にあるはずですVKR
  3. 画像全体を書き換える場合は、 を使用src=LAYOUT_UNDEFINEDして古いデータを破棄できます (より効率的です!)
于 2016-05-05T23:30:16.097 に答える