vulkanmultiview

Vulkan vkCreateImage: The combination of format, type, tiling, usage and flags (...) unsupported when creating depth image


I'm trying to create an offscreen renderpass, but error append before the offscreen stuff, when I create the depth image. I took the prepareOffscreen() fonction from Sascha Willems https://github.com/SaschaWillems/Vulkan/blob/master/examples/offscreen/offscreen.cpp I had to adapt it from C++ to C, and add the multiview support. The ovrVkRenderPass argument is only here to retreive compatible color and depth format.

I 've got the message from the validation layers:

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.

But I can't find my error.

// 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.

    (...)
}

Solution

  • Nicol Bolas helped me find the problem. I now use the format returned by this vr_api function:

    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 ) );
    }
    

    I wonder why these vr_api enums are not directly correlated with Vulkan enums.