Vulkan vkCreateImage:创建深度图像时不支持格式、类型、平铺、用法和标志 (...) 的组合
Vulkan vkCreateImage: The combination of format, type, tiling, usage and flags (...) unsupported when creating depth image
我正在尝试创建离屏渲染通道,但在创建深度图像时,在离屏内容之前附加了错误。
我从 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.
(...)
}
Nicol Bolas 帮我找到了问题所在。我现在使用此 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 枚举没有直接关联。
我正在尝试创建离屏渲染通道,但在创建深度图像时,在离屏内容之前附加了错误。 我从 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.
(...)
}
Nicol Bolas 帮我找到了问题所在。我现在使用此 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 枚举没有直接关联。