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

597 views Asked by At

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.

    (...)
}
1

There are 1 answers

1
Leon On BEST ANSWER

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.