【问题标题】:Vulkan vkCreateImage: The combination of format, type, tiling, usage and flags (...) unsupported when creating depth imageVulkan vkCreateImage:创建深度图像时不支持格式、类型、平铺、用法和标志(...)的组合
【发布时间】:2020-04-10 14:33:41
【问题描述】:

我正在尝试创建一个离屏渲染通道,但是当我创建深度图像时,错误会附加在离屏内容之前。 我从 Sascha Willems https://github.com/SaschaWillems/Vulkan/blob/master/examples/offscreen/offscreen.cpp 那里得到了 prepareOffscreen() 函数 我不得不将它从 C++ 改编为 C,并添加多视图支持。 ovrVkRenderPass 参数仅用于检索兼容的颜色和深度格式。

我收到了来自验证层的消息:

Error: [Validation] Code 180358038 (...) 
vkCreateImage: The combination of format, type, tiling, usage and flags supplied in the VkImageCreateInfo struct is reported by vkGetPhysicalDeviceImageFormatProperties() as unsupported.

但我找不到我的错误。

// Framebuffer for offscreen rendering
typedef struct {
    VkImage image;
    VkDeviceMemory mem;
    VkImageView view;
} FrameBufferAttachment;

typedef struct {
    int width;
    int height;
    VkFramebuffer frameBuffer;
    FrameBufferAttachment color;
    FrameBufferAttachment depth;
    VkRenderPass renderPass;
    VkSampler sampler;
    VkDescriptorImageInfo descriptor;
} OffscreenPass;

OffscreenPass offscreenPass;

static void prepareOffscreen( ovrVkRenderPass * renderPass )
{
    // Setup the offscreen framebuffer for rendering the menu texture
    // The color attachment of this framebuffer will then be used to sample from in the fragment shader of the final pass
    offscreenPass.width = 640;
    offscreenPass.height = 480;

    int layerCount = vk.isMultiview ? 2 : 1;
    const int faceCount = 1;
    const int arrayLayerCount = faceCount * MAX( layerCount, 1 );

    // Color attachment
    VkImageCreateInfo image;
    image.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
    image.imageType = VK_IMAGE_TYPE_2D;
    image.format = renderPass->internalColorFormat;
    image.extent.width = offscreenPass.width;
    image.extent.height = offscreenPass.height;
    image.extent.depth = 1;
    image.mipLevels = 1;
    image.arrayLayers = arrayLayerCount;
    image.samples = VK_SAMPLE_COUNT_1_BIT;
    image.tiling = VK_IMAGE_TILING_OPTIMAL;
    // We will sample directly from the color attachment
    image.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
    image.pNext = NULL;
    image.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
    //image.queueFamilyIndexCount = 0;
    //image.pQueueFamilyIndices = NULL;
    image.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;

    VkMemoryAllocateInfo memAlloc;
    memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
    VkMemoryRequirements memReqs;

    VK( vkDevice->vkCreateImage( vkDevice->device, &image, VK_ALLOCATOR, &offscreenPass.color.image ) );
    VC( vkDevice->vkGetImageMemoryRequirements( vkDevice->device, offscreenPass.color.image, &memReqs ) );
    memAlloc.allocationSize = memReqs.size;
    memAlloc.memoryTypeIndex = VkGetMemoryTypeIndex( vkDevice, memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT );
    VK( vkDevice->vkAllocateMemory( vkDevice->device, &memAlloc, VK_ALLOCATOR, &offscreenPass.color.mem ) );
    VK( vkDevice->vkBindImageMemory( vkDevice->device, offscreenPass.color.image, offscreenPass.color.mem, 0 ) );

    VkImageViewCreateInfo colorImageView;
    colorImageView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
    colorImageView.pNext = NULL;
    colorImageView.flags = 0;
    colorImageView.viewType = VK_IMAGE_VIEW_TYPE_2D;
    colorImageView.format = renderPass->internalColorFormat;
    colorImageView.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
    colorImageView.subresourceRange.baseMipLevel = 0;
    colorImageView.subresourceRange.levelCount = 1;
    colorImageView.subresourceRange.baseArrayLayer = 0; // .baseArrayLayer = 1 is giving a Validation error, don't know why
    colorImageView.subresourceRange.layerCount = layerCount;
    colorImageView.components.r = VK_COMPONENT_SWIZZLE_R;
    colorImageView.components.g = VK_COMPONENT_SWIZZLE_G;
    colorImageView.components.b = VK_COMPONENT_SWIZZLE_B;
    colorImageView.components.a = VK_COMPONENT_SWIZZLE_A;
    colorImageView.image = offscreenPass.color.image;
    VK( vkDevice->vkCreateImageView( vkDevice->device, &colorImageView, VK_ALLOCATOR, &offscreenPass.color.view ) );

    // Create sampler to sample from the attachment in the fragment shader
    VkSamplerCreateInfo samplerInfo;
    samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
    samplerInfo.magFilter = VK_FILTER_LINEAR;
    samplerInfo.minFilter = VK_FILTER_LINEAR;
    samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
    samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
    samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
    samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
    samplerInfo.mipLodBias = 0.0f;
    samplerInfo.maxAnisotropy = 1.0f;
    samplerInfo.minLod = 0.0f;
    samplerInfo.maxLod = 1.0f;
    samplerInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
    samplerInfo.pNext = NULL;
    samplerInfo.anisotropyEnable = VK_FALSE;
    samplerInfo.unnormalizedCoordinates = VK_FALSE;
    samplerInfo.compareEnable = VK_FALSE;
    //samplerInfo.compareOp = VK_COMPARE_OP_NEVER;
    VK( vkDevice->vkCreateSampler( vkDevice->device, &samplerInfo, VK_ALLOCATOR, &offscreenPass.sampler ) );

    // Depth stencil attachment
    image.format = renderPass->depthFormat;
    image.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;

    VK( vkDevice->vkCreateImage( vkDevice->device, &image, VK_ALLOCATOR, &offscreenPass.depth.image ) );        // this last call to vkCreateImage trhow the error:
The combination of format, type, tiling, usage and flags supplied in the VkImageCreateInfo struct is reported by vkGetPhysicalDeviceImageFormatProperties() as unsupported.

    (...)
}

【问题讨论】:

  • "我找不到我的错误。" 您的错误出现在您的代码部分中,您在该部分询问实现是否可以有效地创建具有该格式的图像/等等。
  • 我不明白你的评论,你能说得更清楚些吗?
  • 在创建图像之前,您应该询问实现是否会允许您使用您正在使用的格式/等创建图像(或者您'正在使用规范保证支持的事物的组合)。这就是您的错误所说的:实现不允许您使用格式、平铺等的组合。那么,您从哪里获得使用特定组合的东西创建图像的权限?或者,如果您使用规范保证,规范在哪里保证支持这种组合?
  • 好的,谢谢您的帮助。彩色图像的创建不会触发错误,为什么深度图像创建会触发?如您所见,我只更改了格式和用法,并且格式来自有效的渲染通道。 (留下回复,以便我验证。)
  • "如您所见,我只更改了格式和用法" "仅"?为什么你认为这在某种程度上无关紧要?我不知道如何比我说得更清楚:“在创建图像之前,您应该询问实现是否允许您使用您正在使用的格式/等创建图像(或者您正在使用规范保证支持的组合)。”这不是可选的

标签: vulkan multiview


【解决方案1】:

尼可波拉斯帮我找到了问题。我现在使用这个 vr_api 函数返回的格式:

static VkFormat ovrGpuDepthBuffer_InternalSurfaceDepthFormat( const ovrSurfaceDepthFormat depthFormat )
{
return  ( ( depthFormat == OVR_SURFACE_DEPTH_FORMAT_D16 ) ? VK_FORMAT_D16_UNORM :
        ( ( depthFormat == OVR_SURFACE_DEPTH_FORMAT_D24 ) ? VK_FORMAT_D24_UNORM_S8_UINT :
        VK_FORMAT_UNDEFINED ) );
}

我想知道为什么这些 vr_api 枚举与 Vulkan 枚举不直接相关。

【讨论】:

  • Nicol Bolas 没有发布答案,所以我接受我自己的答案以结束这个问题。
猜你喜欢
  • 2012-08-15
  • 2021-12-17
  • 2019-08-03
  • 1970-01-01
  • 1970-01-01
  • 2021-11-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多