Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.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-异步纹理上载-图像转换问题_C_Vulkan - Fatal编程技术网

C Vulkan-异步纹理上载-图像转换问题

C Vulkan-异步纹理上载-图像转换问题,c,vulkan,C,Vulkan,我使用传输队列将数据上传到GPU本地内存,供图形队列使用。我相信我需要3个屏障,一个用于从传输队列中释放纹理对象,一个用于在图形队列中获取纹理对象,还有一个用于将纹理对象从transfer_DST_OPTIMAL转换为SHADER_READ_OPTIMAL。我认为我的屏障是不正确的,因为这是我得到的错误,而且,我在Nvidia硬件上看到了正确的渲染输出。是否缺少任何同步 UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout(ERROR /

我使用传输队列将数据上传到GPU本地内存,供图形队列使用。我相信我需要3个屏障,一个用于从传输队列中释放纹理对象,一个用于在图形队列中获取纹理对象,还有一个用于将纹理对象从transfer_DST_OPTIMAL转换为SHADER_READ_OPTIMAL。我认为我的屏障是不正确的,因为这是我得到的错误,而且,我在Nvidia硬件上看到了正确的渲染输出。是否缺少任何同步

UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout(ERROR / SPEC): msgNum: 1303270965 - 
Validation Error: [ UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout ] Object 0: 
handle = 0x562696461ca0, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0x4dae5635 | 
Submitted command buffer expects VkImage 0x1c000000001c[] (subresource: aspectMask 0x1 array 
layer 0, mip level 0) to be in layout VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL--instead, 
current layout is VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL.
我认为我做错的是没有正确地指定stagemask

    VkImageMemoryBarrier tex_barrier = {0};
    /* layout transition - UNDEFINED -> TRANSFER_DST */
    tex_barrier.srcAccessMask = 0;
    tex_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
    tex_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    tex_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
    tex_barrier.srcQueueFamilyIndex = -1; 
    tex_barrier.dstQueueFamilyIndex = -1;
    tex_barrier.subresourceRange = (VkImageSubresourceRange) { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };

    vkCmdPipelineBarrier(transfer_cmdbuffs[0], 
                         VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
                         VK_PIPELINE_STAGE_TRANSFER_BIT,
                         0,
                         0, NULL, 0, NULL, 1, &tex_barrier);

    /* queue ownership transfer */
    tex_barrier.srcAccessMask = 0;
    tex_barrier.dstAccessMask = 0;
    tex_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
    tex_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
    tex_barrier.srcQueueFamilyIndex = device.transfer_queue_family_index;
    tex_barrier.dstQueueFamilyIndex = device.graphics_queue_family_index;
    
    vkCmdPipelineBarrier(transfer_cmdbuffs[0],
                         VK_PIPELINE_STAGE_TRANSFER_BIT,
                         VK_PIPELINE_STAGE_TRANSFER_BIT,
                         0,
                         0, NULL, 0, NULL, 1, &tex_barrier);
                         
    tex_barrier.srcAccessMask = 0;
    tex_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
    tex_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
    tex_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
    tex_barrier.srcQueueFamilyIndex = device.transfer_queue_family_index;
    tex_barrier.dstQueueFamilyIndex = device.graphics_queue_family_index;
    
    vkCmdPipelineBarrier(transfer_cmdbuffs[0],
                         VK_PIPELINE_STAGE_TRANSFER_BIT,
                         VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
                         0,
                         0, NULL, 0, NULL, 1, &tex_barrier);
    

所有权转移是一个双向的过程:转移源必须释放资源,接收者必须获取资源。“来源”和“接收者”,我指的是队列本身。你不能仅仅给队列一个资源的所有权;该队列必须发出命令以声明其所有权

您需要在源队列上提交释放屏障操作。它必须指定源队列族和目标队列族。然后,您必须使用相同的源和目标在接收队列上提交获取屏障操作。您必须通过信号量确保这些操作的顺序。因此,acquire的
vkQueueSubmit
调用必须等待来自发布操作提交的信号量(时间轴信号量也可以工作)


现在,由于这些是管道/内存屏障,您也可以自由地指定布局转换。您不需要第三个屏障来更改布局,但两个屏障都必须为获取/释放操作指定相同的源/目标布局。

您是否像伪代码所建议的那样,向相同的命令缓冲区发出这些命令?因为我很确定这行不通。相同的命令缓冲区,相同的提交队列。提交之间是否需要信号量同步操作?