我正在努力理解我需要使用 Vulkan API 查询的一个简单功能:我需要确定我的 GPU 支持的所有纹理格式。经过一番搜索,我发现了这段代码:
uint32_t formatCount;
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, nullptr);
if (formatCount != 0) {
details.formats.resize(formatCount);
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, details.formats.data());
int counter = 0;
int numFormats = details.formats.size();
for (const auto& format : details.formats) {
VkFormat vkFormat = format.format;
VkColorSpaceKHR colorSpace = format.colorSpace;
std::cout << "[" << counter << "] Format: " <<
vkFormatToString(vkFormat) <<
", Color Space: " << colorSpace << std::endl;
counter++;
}
}
我收到的输出仅限于:
[0] Format: VK_FORMAT_R8G8B8A8_UNORM, Color Space: 0
[1] Format: VK_FORMAT_B8G8R8A8_UNORM, Color Space: 0
[2] Format: VK_FORMAT_R8G8B8A8_SRGB, Color Space: 0
[3] Format: VK_FORMAT_B8G8R8A8_SRGB, Color Space: 0
这看起来不正确,因为我使用的是强大的 AMD GPU (Radeon),它支持“VK_FORMAT_BC1_RGBA_UNORM_BLOCK”等压缩格式。这是显而易见的,因为我可以使用这种格式成功创建图像:
imageInfo.format = VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
imageInfo.tiling = tiling;
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
imageInfo.usage = usage;
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
if (vkCreateImage(device, &imageInfo, nullptr, &image) != VK_SUCCESS) {
throw std::runtime_error("failed to create image!");
}
我怀疑我之前的代码只枚举了 KHR Surface 功能,而不是 GPU 纹理格式。
总而言之,如何查询可用的GPU纹理格式?
非常感谢您的协助。
vkGetPhysicalDeviceSurfaceFormatsKHR
仅用于查询作为 VK_KHR_surface 一部分的表面的 GPU 支持的格式。
vkGetPhysicalDeviceFormatProperties
archive查询对图像格式的支持。
void IterateFormats(VkFormat min, VkFormat max)
{
for(VkFormat fmt = min; fmt <= max; ++fmt)
{
VkFormatProperties properties{};
vkGetPhysicalDeviceFormatProperties(device, fmt, &properties);
SaveFormat(fmt, properties);
}
}
void IterateFormatGroups()
{
// VK_VERSION_1_0
IterateFormats(VK_FORMAT_R4G4_UNORM_PACK8, VK_FORMAT_ASTC_12x12_SRGB_BLOCK);
// VK_VERSION_1_1, VK_KHR_sampler_ycbcr_conversion
IterateFormats(VK_FORMAT_G8B8G8R8_422_UNORM, VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM);
// VK_VERSION_1_3, VK_EXT_ycbcr_2plane_444_formats
IterateFormats(VK_FORMAT_G8_B8R8_2PLANE_444_UNORM, VK_FORMAT_G16_B16R16_2PLANE_444_UNORM);
// VK_VERSION_1_3, VK_EXT_4444_formats
IterateFormats(VK_FORMAT_A4R4G4B4_UNORM_PACK16, VK_FORMAT_A4B4G4R4_UNORM_PACK16);
// VK_VERSION_1_3, VK_EXT_texture_compression_astc_hdr
IterateFormats(VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK, VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK);
// VK_IMG_format_pvrtc
IterateFormats(VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG, VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG);
// VK_NV_optical_flow
IterateFormats(VK_FORMAT_R16G16_SFIXED5_NV, VK_FORMAT_R16G16_SFIXED5_NV);
// VK_KHR_maintenance5
IterateFormats(VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR, VK_FORMAT_A8_UNORM_KHR);
}