Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for format feature flags 2 #209

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -230,3 +230,11 @@ redist/*.zip

devdatabase.ini
/db.ini

android-build/**
tools/*.zip
tools/*.dmg
tools/*.apk
tools/*.AppImage

log.txt
3 changes: 2 additions & 1 deletion VulkanContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
*
* Vulkan hardware capability viewer
*
* Copyright (C) 2016-2022 by Sascha Willems (www.saschawillems.de)
* Copyright (C) 2016-2023 by Sascha Willems (www.saschawillems.de)
*
* This code is free software, you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -31,6 +31,7 @@ struct VulkanContext
PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR = nullptr;
PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR = nullptr;
PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR = nullptr;
PFN_vkGetPhysicalDeviceFormatProperties2 vkGetPhysicalDeviceFormatProperties2 = nullptr;
};

extern VulkanContext vulkanContext;
Expand Down
2 changes: 1 addition & 1 deletion android/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0"?>
<manifest package="de.saschawillems.vulkancapsviewer" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="3.42" android:versionCode="40" android:installLocation="auto">
<manifest package="de.saschawillems.vulkancapsviewer" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="3.50" android:versionCode="41" android:installLocation="auto">
<!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
Remove the comment if you do not require these default permissions. -->
<!-- %%INSERT_PERMISSIONS -->
Expand Down
92 changes: 69 additions & 23 deletions vulkanDeviceInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,37 +101,76 @@ void VulkanDeviceInfo::readLayers()

void VulkanDeviceInfo::readSupportedFormats()
{
// A note before adding new formats in here: In order for them to be properly displayed, formats also need to be added to the database

assert(device != NULL);
qInfo() << "Reading formats";
// Base formats
int32_t firstFormat = VK_FORMAT_R4G4_UNORM_PACK8;
int32_t lastFormat = VK_FORMAT_ASTC_12x12_SRGB_BLOCK;
if (hasFormatFeatureFlags2) {
qInfo() << "Reading formats using VK_KHR_format_feature_flags2";
} else {
qInfo() << "Reading formats";
}

// Generate format listing from core and supported extensions
std::vector<uint64_t> formatList{};

// Core formats
uint64_t firstFormat = VK_FORMAT_R4G4_UNORM_PACK8;
uint64_t lastFormat = VK_FORMAT_ASTC_12x12_SRGB_BLOCK;
for (int32_t format = firstFormat; format <= lastFormat; format++) {
VulkanFormatInfo formatInfo = {};
formatInfo.format = (VkFormat)format;
vkGetPhysicalDeviceFormatProperties(device, formatInfo.format, &formatInfo.properties);
formatInfo.supported = (formatInfo.properties.linearTilingFeatures != 0) || (formatInfo.properties.optimalTilingFeatures != 0) || (formatInfo.properties.bufferFeatures != 0);
formats.push_back(formatInfo);
formatList.push_back(format);
}

// VK_KHR_sampler_ycbcr_conversion
if (extensionSupported(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME)) {
for (int32_t format = VK_FORMAT_G8B8G8R8_422_UNORM; format < VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM; format++) {
VulkanFormatInfo formatInfo = {};
formatInfo.format = (VkFormat)format;
vkGetPhysicalDeviceFormatProperties(device, formatInfo.format, &formatInfo.properties);
formatInfo.supported = (formatInfo.properties.linearTilingFeatures != 0) || (formatInfo.properties.optimalTilingFeatures != 0) || (formatInfo.properties.bufferFeatures != 0);
formats.push_back(formatInfo);
formatList.push_back((VkFormat)format);
}
}

// VK_IMG_FORMAT_PVRTC_EXTENSION_NAME
if (extensionSupported(VK_IMG_FORMAT_PVRTC_EXTENSION_NAME)) {
for (int32_t format = VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG; format < VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG; format++) {
VulkanFormatInfo formatInfo = {};
formatInfo.format = (VkFormat)format;
vkGetPhysicalDeviceFormatProperties(device, formatInfo.format, &formatInfo.properties);
formatInfo.supported = (formatInfo.properties.linearTilingFeatures != 0) || (formatInfo.properties.optimalTilingFeatures != 0) || (formatInfo.properties.bufferFeatures != 0);
formats.push_back(formatInfo);
formatList.push_back((VkFormat)format);
}
}

for (auto i = 0; i < formatList.size(); i++) {
VkFormat format = (VkFormat)formatList[i];

VulkanFormatInfo formatInfo = {};
formatInfo.format = (VkFormat)format;

// Use the same data structure for both base and newer feature flag bits
// As the _flags2 also contain the base flags this will work both in the app and the database

if (hasFormatFeatureFlags2) {
// Using VK_KHR_format_feature_flags2
VkFormatProperties3 formatProperties3{};
formatProperties3.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR;

VkFormatProperties2 formatProperties2{};
formatProperties2.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
formatProperties2.pNext = &formatProperties3;

vulkanContext.vkGetPhysicalDeviceFormatProperties2(device, formatInfo.format, &formatProperties2);

formatInfo.bufferFeatures = formatProperties3.bufferFeatures;
formatInfo.linearTilingFeatures = formatProperties3.linearTilingFeatures;
formatInfo.optimalTilingFeatures = formatProperties3.optimalTilingFeatures;

formatInfo.isFeatureFlags2 = true;
}
else {
VkFormatProperties formatProperties{};
vkGetPhysicalDeviceFormatProperties(device, formatInfo.format, &formatProperties);

formatInfo.bufferFeatures = formatProperties.bufferFeatures;
formatInfo.linearTilingFeatures = formatProperties.linearTilingFeatures;
formatInfo.optimalTilingFeatures = formatProperties.optimalTilingFeatures;
}

formatInfo.supported = (formatInfo.linearTilingFeatures != 0) || (formatInfo.optimalTilingFeatures != 0) || (formatInfo.bufferFeatures != 0);
formats.push_back(formatInfo);
}
}

Expand Down Expand Up @@ -418,12 +457,19 @@ void VulkanDeviceInfo::readPhysicalProperties()
core13Properties["maxBufferSize"] = QVariant::fromValue(coreProps13.maxBufferSize).toString();
}
}

if (extensionSupported(VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME)) {
qInfo() << "Device supports VK_KHR_format_feature_flags2";
hasFormatFeatureFlags2 = true;
}

properties["hasFormatFeatureFlags2"] = hasFormatFeatureFlags2;
}

void VulkanDeviceInfo::readPhysicalFeatures()
{
assert(device != NULL);
qInfo() << "Reading physical feattures";
qInfo() << "Reading physical features";
vkGetPhysicalDeviceFeatures(device, &deviceFeatures);

features.clear();
Expand Down Expand Up @@ -887,9 +933,9 @@ QJsonObject VulkanDeviceInfo::toJson(QString submitter, QString comment)
QJsonArray jsonFormat;
jsonFormat.append((QJsonValue(format.format)));
QJsonObject jsonFormatFeatures;
jsonFormatFeatures["linearTilingFeatures"] = QVariant::fromValue(format.properties.linearTilingFeatures).toString();
jsonFormatFeatures["optimalTilingFeatures"] = QVariant::fromValue(format.properties.optimalTilingFeatures).toString();
jsonFormatFeatures["bufferFeatures"] = QVariant::fromValue(format.properties.bufferFeatures).toString();
jsonFormatFeatures["linearTilingFeatures"] = QVariant::fromValue(format.linearTilingFeatures).toString();
jsonFormatFeatures["optimalTilingFeatures"] = QVariant::fromValue(format.optimalTilingFeatures).toString();
jsonFormatFeatures["bufferFeatures"] = QVariant::fromValue(format.bufferFeatures).toString();
jsonFormatFeatures["supported"] = format.supported;
jsonFormat.append(jsonFormatFeatures);
jsonFormats.append(jsonFormat);
Expand Down
1 change: 1 addition & 0 deletions vulkanDeviceInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class VulkanDeviceInfo: public VulkanDeviceInfoExtensions
QVariantMap core13Features;
bool hasSubgroupProperties = false;
bool hasFeaturModifyingTool = false;
bool hasFormatFeatureFlags2 = false;
QVariantMap subgroupProperties;
QVariantMap core11Properties;
QVariantMap core12Properties;
Expand Down
11 changes: 9 additions & 2 deletions vulkanFormatInfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*
* Layer information struct
*
* Copyright (C) 2015 by Sascha Willems (www.saschawillems.de)
* Copyright (C) 2015-2024 by Sascha Willems (www.saschawillems.de)
*
* This code is free software, you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
Expand All @@ -27,6 +27,13 @@
struct VulkanFormatInfo
{
VkFormat format;
VkFormatProperties properties;

uint64_t linearTilingFeatures;
uint64_t optimalTilingFeatures;
uint64_t bufferFeatures;

bool isFeatureFlags2{ false };

// @todo: deprecate
bool supported;
};
114 changes: 37 additions & 77 deletions vulkancapsviewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include <QApplication>
#include <qnamespace.h>
#include <assert.h>
#include <unordered_map>
#include <settingsDialog.h>
#include "submitDialog.h"

Expand Down Expand Up @@ -81,7 +82,7 @@ extern "C" const char *getWorkingFolderForiOS(void);

using std::to_string;

const QString VulkanCapsViewer::version = "3.42";
const QString VulkanCapsViewer::version = "3.50";
const QString VulkanCapsViewer::reportVersion = "3.3";

OSInfo getOperatingSystem()
Expand Down Expand Up @@ -727,6 +728,12 @@ bool VulkanCapsViewer::initVulkan()
deviceProperties2Available = false;
QMessageBox::warning(this, tr("Error"), "Could not get function pointer for vkGetPhysicalDeviceProperties2KHR (even though extension is enabled!)\nNew features and properties won't be displayed!");
}
// Function pointers for new format properties
vulkanContext.vkGetPhysicalDeviceFormatProperties2 = reinterpret_cast<PFN_vkGetPhysicalDeviceFormatProperties2>(vkGetInstanceProcAddr(vulkanContext.instance, "vkGetPhysicalDeviceFormatProperties2"));
if (!vulkanContext.vkGetPhysicalDeviceFormatProperties2) {
deviceFormatProperties2Available = false;
QMessageBox::warning(this, tr("Error"), "Could not get function pointer for vkGetPhysicalDeviceFormatProperties2 (even though extension is enabled!)\nNew format properties won't be displayed!");
}
}

vulkanContext.vkGetPhysicalDeviceSurfaceSupportKHR = reinterpret_cast<PFN_vkGetPhysicalDeviceSurfaceSupportKHR>(vkGetInstanceProcAddr(vulkanContext.instance, "vkGetPhysicalDeviceSurfaceSupportKHR"));
Expand Down Expand Up @@ -1538,16 +1545,6 @@ void VulkanCapsViewer::displayOSInfo(VulkanDeviceInfo& device)
}
}

void addFlagModelItem(QStandardItem *parent, QString flagName, bool flag)
{
if (flag)
{
QList<QStandardItem *> flagItems;
flagItems << new QStandardItem(flagName);
parent->appendRow(flagItems);
}
}

void VulkanCapsViewer::displayDeviceFormats(VulkanDeviceInfo *device)
{
models.formats.clear();
Expand All @@ -1557,11 +1554,11 @@ void VulkanCapsViewer::displayDeviceFormats(VulkanDeviceInfo *device)
QList<QStandardItem *> rowItems;
rowItems << new QStandardItem(QString::fromStdString(vulkanResources::formatString(format.format)));

std::vector<VkFormatFeatureFlags> featureFlags =
std::vector<uint64_t> featureFlags =
{
format.properties.linearTilingFeatures,
format.properties.optimalTilingFeatures,
format.properties.bufferFeatures
format.linearTilingFeatures,
format.optimalTilingFeatures,
format.bufferFeatures
};

uint32_t i = 1;
Expand All @@ -1573,75 +1570,38 @@ void VulkanCapsViewer::displayDeviceFormats(VulkanDeviceInfo *device)
}

rootItem->appendRow(rowItems);

struct featureSet {
std::string name;
VkFlags flags;
};
std::vector<featureSet> featureSets =
{
{ "Linear tiling flags", format.properties.linearTilingFeatures },
{ "Optimal tiling flags", format.properties.optimalTilingFeatures },
{ "Buffer features flags", format.properties.bufferFeatures }
std::unordered_map<std::string, uint64_t> featureSets = {
{ "Linear tiling flags", format.linearTilingFeatures },
{ "Optimal tiling flags", format.optimalTilingFeatures },
{ "Buffer features flags", format.bufferFeatures }
};

if (format.supported)
// Always use feature2 enums, as they contain all initial enums
for (auto& featureSet : featureSets)
{
for (auto& featureSet : featureSets)
{
QList<QStandardItem *> flagItems;
flagItems << new QStandardItem(QString::fromStdString(featureSet.name));
QList<QStandardItem*> flagItems;
flagItems << new QStandardItem(QString::fromStdString(featureSet.first));

if (featureSet.flags == 0)
{
QList<QStandardItem *> flagItem;
flagItem << new QStandardItem("none");
flagItems[0]->appendRow(flagItem);
}
else
{
#define ADD_FLAG(flag) \
if (featureSet.flags & flag) \
{ \
QList<QStandardItem *> flagItem; \
QString flagname(#flag); \
flagname = flagname.replace("VK_FORMAT_FEATURE_", ""); \
flagItem << new QStandardItem(flagname); \
flagItems[0]->appendRow(flagItem); \
if (featureSet.second == 0)
{
QList<QStandardItem*> flagItem;
flagItem << new QStandardItem("none");
flagItems[0]->appendRow(flagItem);
}
else
{
for (auto& formatFlag : vulkanResources::formatFeatureFlags2) {
if (featureSet.second & formatFlag) {
QList<QStandardItem*> flagItem;
QString flagname = vulkanResources::formatFeature2String(formatFlag);
flagname = flagname.replace("VK_FORMAT_FEATURE_2_", "");
flagItem << new QStandardItem(flagname);
flagItems[0]->appendRow(flagItem);
}

// Core
ADD_FLAG(VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)
ADD_FLAG(VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)
ADD_FLAG(VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT)
ADD_FLAG(VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT)
ADD_FLAG(VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT)
ADD_FLAG(VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT)
ADD_FLAG(VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)
ADD_FLAG(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)
ADD_FLAG(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT)
ADD_FLAG(VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
ADD_FLAG(VK_FORMAT_FEATURE_BLIT_SRC_BIT)
ADD_FLAG(VK_FORMAT_FEATURE_BLIT_DST_BIT)
// 1.1
ADD_FLAG(VK_FORMAT_FEATURE_TRANSFER_SRC_BIT)
ADD_FLAG(VK_FORMAT_FEATURE_TRANSFER_DST_BIT)
ADD_FLAG(VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT)
ADD_FLAG(VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT)
ADD_FLAG(VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT)
ADD_FLAG(VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT)
ADD_FLAG(VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT)
ADD_FLAG(VK_FORMAT_FEATURE_DISJOINT_BIT)
ADD_FLAG(VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT)

// EXT
ADD_FLAG(VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)
ADD_FLAG(VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG)
}

rowItems[0]->appendRow(flagItems);

}

rowItems[0]->appendRow(flagItems);
}
}

Expand Down
1 change: 1 addition & 0 deletions vulkancapsviewer.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class VulkanCapsViewer : public QMainWindow
std::vector<VulkanLayerInfo> instanceLayers;
std::vector<VkExtensionProperties> instanceExtensions;
bool deviceProperties2Available = false;
bool deviceFormatProperties2Available = false;
VulkanDatabase database;
void checkReportDatabaseState();
VulkanCapsViewer(QWidget *parent = 0);
Expand Down
4 changes: 2 additions & 2 deletions vulkandatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*
* Database communication class implementation
*
* Copyright (C) 2016-2023 by Sascha Willems (www.saschawillems.de)
* Copyright (C) 2016-2024 by Sascha Willems (www.saschawillems.de)
*
* This code is free software, you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -140,7 +140,7 @@ bool VulkanDatabase::uploadReport(QJsonObject json, QString& message)
QJsonDocument doc(json);
httpPart.setBody(doc.toJson());
multiPart->append(httpPart);
QUrl qurl(databaseUrl + "api/v3/uploadreport.php");
QUrl qurl(databaseUrl + "api/v4/uploadreport.php");
QNetworkRequest request(qurl);
QNetworkReply* reply = manager->post(request, multiPart);
multiPart->setParent(reply);
Expand Down
Loading
Loading