vulkaninfo: shorten format dump in console
authorPetr Kraus <petr_kraus@email.cz>
Mon, 21 Jan 2019 23:12:29 +0000 (00:12 +0100)
committerjeremyk-lunarg <jeremyk@lunarg.com>
Tue, 22 Jan 2019 19:47:01 +0000 (12:47 -0700)
vulkaninfo/vulkaninfo.c

index e3011a9..4fa2acf 100644 (file)
@@ -2001,24 +2001,192 @@ bool FormatRangeSupported(const struct FormatRange *format_range, const struct A
     return false;
 }
 
+bool FormatPropsEq(const VkFormatProperties *props1, const VkFormatProperties *props2) {
+    if (props1->bufferFeatures == props2->bufferFeatures && props1->linearTilingFeatures == props2->linearTilingFeatures &&
+        props1->optimalTilingFeatures == props2->optimalTilingFeatures) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+struct PropFormats {
+    VkFormatProperties props;
+
+    uint32_t format_count;
+    uint32_t format_reserve;
+    VkFormat *formats;
+};
+
+void FormatPropsShortenedDump(const struct AppGpu *gpu) {
+    const VkFormatProperties unsupported_prop = {0};
+    uint32_t unique_props_count = 1;
+    uint32_t unique_props_reserve = 50;
+    struct PropFormats *prop_map = malloc(sizeof(struct PropFormats) * unique_props_reserve);
+    if (!prop_map) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
+    prop_map[0].props = unsupported_prop;
+    prop_map[0].format_count = 0;
+    prop_map[0].format_reserve = 20;
+    prop_map[0].formats = malloc(sizeof(VkFormat) * prop_map[0].format_reserve);
+    if (!prop_map[0].formats) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+    for (uint32_t ri = 0; ri < ARRAY_SIZE(supported_format_ranges); ++ri) {
+        struct FormatRange format_range = supported_format_ranges[ri];
+        if (FormatRangeSupported(&format_range, gpu)) {
+            for (VkFormat fmt = format_range.first_format; fmt <= format_range.last_format; ++fmt) {
+                VkFormatProperties props;
+                vkGetPhysicalDeviceFormatProperties(gpu->obj, fmt, &props);
+
+                uint32_t formats_prop_i = 0;
+                for (; formats_prop_i < unique_props_count; ++formats_prop_i) {
+                    if (FormatPropsEq(&prop_map[formats_prop_i].props, &props)) break;
+                }
+
+                if (formats_prop_i < unique_props_count) {
+                    struct PropFormats *propFormats = &prop_map[formats_prop_i];
+                    ++propFormats->format_count;
+
+                    if (propFormats->format_count > propFormats->format_reserve) {
+                        propFormats->format_reserve *= 2;
+                        propFormats->formats = realloc(propFormats->formats, sizeof(VkFormat) * propFormats->format_reserve);
+                        if (!propFormats->formats) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
+                    }
+
+                    propFormats->formats[propFormats->format_count - 1] = fmt;
+                } else {
+                    assert(formats_prop_i == unique_props_count);
+                    ++unique_props_count;
+
+                    if (unique_props_count > unique_props_reserve) {
+                        unique_props_reserve *= 2;
+                        prop_map = realloc(prop_map, sizeof(struct PropFormats) * unique_props_reserve);
+                        if (!prop_map) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
+                    }
+
+                    struct PropFormats *propFormats = &prop_map[formats_prop_i];
+                    propFormats->props = props;
+                    propFormats->format_count = 1;
+                    propFormats->format_reserve = 20;
+                    propFormats->formats = malloc(sizeof(VkFormat) * propFormats->format_reserve);
+                    if (!propFormats->formats) ERR_EXIT(VK_ERROR_OUT_OF_HOST_MEMORY);
+                    propFormats->formats[0] = fmt;
+                }
+            }
+        }
+    }
+
+    for (uint32_t pi = 1; pi < unique_props_count; ++pi) {
+        struct PropFormats *propFormats = &prop_map[pi];
+
+        for (uint32_t fi = 0; fi < propFormats->format_count; ++fi) {
+            const VkFormat fmt = propFormats->formats[fi];
+
+            printf("\nFORMAT_%s", VkFormatString(fmt));
+
+            if (fi < propFormats->format_count - 1)
+                printf(",");
+            else
+                printf(":");
+        }
+
+        struct {
+            const char *name;
+            VkFlags flags;
+        } features[3];
+
+        features[0].name = "linearTiling   FormatFeatureFlags";
+        features[0].flags = propFormats->props.linearTilingFeatures;
+        features[1].name = "optimalTiling  FormatFeatureFlags";
+        features[1].flags = propFormats->props.optimalTilingFeatures;
+        features[2].name = "bufferFeatures FormatFeatureFlags";
+        features[2].flags = propFormats->props.bufferFeatures;
+
+        for (uint32_t i = 0; i < ARRAY_SIZE(features); ++i) {
+            printf("\n\t%s:", features[i].name);
+            if (features[i].flags == 0) {
+                printf("\n\t\tNone");
+            } else {
+                printf(
+                    "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+                    ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT"
+                                                                               : ""),  // 0x0001
+                    ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_BIT"
+                                                                               : ""),  // 0x0002
+                    ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT)
+                         ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT"
+                         : ""),  // 0x0004
+                    ((features[i].flags & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT)
+                         ? "\n\t\tVK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT"
+                         : ""),  // 0x0008
+                    ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT)
+                         ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT"
+                         : ""),  // 0x0010
+                    ((features[i].flags & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT)
+                         ? "\n\t\tVK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT"
+                         : ""),  // 0x0020
+                    ((features[i].flags & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) ? "\n\t\tVK_FORMAT_FEATURE_VERTEX_BUFFER_BIT"
+                                                                               : ""),  // 0x0040
+                    ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT"
+                                                                                  : ""),  // 0x0080
+                    ((features[i].flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT)
+                         ? "\n\t\tVK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT"
+                         : ""),  // 0x0100
+                    ((features[i].flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
+                         ? "\n\t\tVK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT"
+                         : ""),                                                                                            // 0x0200
+                    ((features[i].flags & VK_FORMAT_FEATURE_BLIT_SRC_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_SRC_BIT" : ""),  // 0x0400
+                    ((features[i].flags & VK_FORMAT_FEATURE_BLIT_DST_BIT) ? "\n\t\tVK_FORMAT_FEATURE_BLIT_DST_BIT" : ""),  // 0x0800
+                    ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)
+                         ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT"
+                         : ""),  // 0x1000
+                    ((features[i].flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG)
+                         ? "\n\t\tVK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG"
+                         : ""),  // 0x2000
+                    ((features[i].flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR) ? "\n\t\tVK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR"
+                                                                                  : ""),  // 0x4000
+                    ((features[i].flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR) ? "\n\t\tVK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR"
+                                                                                  : ""));  // 0x8000
+            }
+
+            printf("\n");
+        }
+    }
+
+    printf("\nUnsupported formats:");
+    if (prop_map[0].format_count == 0) printf("\nNone");
+    for (uint32_t fi = 0; fi < prop_map[0].format_count; ++fi) {
+        const VkFormat fmt = prop_map[0].formats[fi];
+
+        printf("\nFORMAT_%s", VkFormatString(fmt));
+    }
+
+    // cleanup
+    for (uint32_t pi = 0; pi < unique_props_count; ++pi) free(prop_map[pi].formats);
+    free(prop_map);
+}
+
 static void AppDevDump(const struct AppGpu *gpu, FILE *out) {
     if (html_output) {
         fprintf(out, "\t\t\t\t\t<details><summary>Format Properties</summary>\n");
     } else if (human_readable_output) {
         printf("Format Properties:\n");
-        printf("==================");
+        printf("==================\n");
     }
     if (json_output) {
         printf(",\n");
         printf("\t\"ArrayOfVkFormatProperties\": [");
     }
 
-    bool first_in_list = true;   // Used for commas in json output
-    for (uint32_t i = 0; i < sizeof(supported_format_ranges)/sizeof(supported_format_ranges[0]); i++) {
-        struct FormatRange format_range = supported_format_ranges[i];
-        if (FormatRangeSupported(&format_range, gpu)) {
-            for (VkFormat fmt = format_range.first_format; fmt <= format_range.last_format; ++fmt) {
-                AppDevDumpFormatProps(gpu, fmt, &first_in_list, out);
+    if (human_readable_output) {
+        FormatPropsShortenedDump(gpu);
+    } else {
+        bool first_in_list = true;  // Used for commas in json output
+        for (uint32_t i = 0; i < ARRAY_SIZE(supported_format_ranges); ++i) {
+            struct FormatRange format_range = supported_format_ranges[i];
+            if (FormatRangeSupported(&format_range, gpu)) {
+                for (VkFormat fmt = format_range.first_format; fmt <= format_range.last_format; ++fmt) {
+                    AppDevDumpFormatProps(gpu, fmt, &first_in_list, out);
+                }
             }
         }
     }