4#include <QtCore/qcoreapplication.h>
5#include <QtCore/qfile.h>
6#include <QtCore/qfileinfo.h>
7#include <QtCore/qlist.h>
8#include <QtCore/qmap.h>
9#include <QtCore/qxmlstream.h>
36 QList<Command>
commands()
const {
return m_commands; }
44 void parseFeatureRequire(
const QString &versionDefine);
46 Command parseCommand();
47 TypedName parseParamOrProto(
const QString &
tag);
51 QXmlStreamReader m_reader;
52 QList<Command> m_commands;
53 QMap<QString, QStringList> m_versionCommandMapping;
64 m_reader.setDevice(&m_file);
67 m_versionCommandMapping.
clear();
69 while (!m_reader.atEnd()) {
71 if (m_reader.isStartElement()) {
82void VkSpecParser::skip()
85 while (!m_reader.atEnd()) {
87 if (m_reader.isEndElement() && m_reader.name() ==
tag)
92void VkSpecParser::parseFeature()
99 for (
const QXmlStreamAttribute &attr : m_reader.attributes()) {
101 api = attr.value().toString().trimmed();
103 versionName = attr.value().toString().
trimmed();
107 while (!m_reader.atEnd()) {
109 if (m_reader.isEndElement() && m_reader.name() ==
QStringLiteral(
"feature"))
111 if (m_reader.isStartElement() && m_reader.name() ==
QStringLiteral(
"require")) {
113 parseFeatureRequire(versionName);
118void VkSpecParser::parseFeatureRequire(
const QString &versionDefine)
123 while (!m_reader.atEnd()) {
125 if (m_reader.isEndElement() && m_reader.name() ==
QStringLiteral(
"require"))
127 if (m_reader.isStartElement() && m_reader.name() ==
QStringLiteral(
"command")) {
128 for (
const QXmlStreamAttribute &attr : m_reader.attributes()) {
130 m_versionCommandMapping[versionDefine].append(attr.value().toString().trimmed());
136void VkSpecParser::parseCommands()
141 while (!m_reader.atEnd()) {
143 if (m_reader.isEndElement() && m_reader.name() ==
QStringLiteral(
"commands"))
145 if (m_reader.isStartElement() && m_reader.name() ==
QStringLiteral(
"command")) {
146 const Command
c = parseCommand();
147 if (!
c.cmd.name.isEmpty())
163 while (!m_reader.atEnd()) {
165 if (m_reader.isEndElement() && m_reader.name() ==
QStringLiteral(
"command"))
167 if (m_reader.isStartElement()) {
170 if (m_reader.name() == protoStr) {
171 c.cmd = parseParamOrProto(protoStr);
172 }
else if (m_reader.name() == paramStr) {
173 c.args.append(parseParamOrProto(paramStr));
180 c.deviceLevel =
false;
181 if (!
c.args.isEmpty()) {
187 if (dispatchableDeviceAndChildTypes.contains(
c.args[0].type)
190 c.deviceLevel =
true;
201 while (!m_reader.atEnd()) {
203 if (m_reader.isEndElement() && m_reader.name() ==
tag)
205 if (m_reader.isStartElement()) {
207 t.name = parseName();
212 auto text = m_reader.text().trimmed();
215 t.typeSuffix +=
text;
217 if (!
t.type.isEmpty())
228QString VkSpecParser::parseName()
231 while (!m_reader.atEnd()) {
233 if (m_reader.isEndElement() && m_reader.name() ==
QStringLiteral(
"name"))
235 name += m_reader.text();
237 return name.trimmed();
245 if (!
c.args.isEmpty()) {
254 (
a.type.endsWith(u
'*') ?
"" :
" "),
270 if (!
c.args.isEmpty()) {
307 m_str +=
"\n// This file is automatically generated by qvkgen. Do not edit.\n";
313 const QMap<QString, QStringList> &versionCommandMapping,
323 static const char *
s =
325"#ifndef QVULKANFUNCTIONS_H\n"
326"#define QVULKANFUNCTIONS_H\n"
329"#pragma qt_no_master_include\n"
332"#include <QtGui/qtguiglobal.h>\n"
334"#if QT_CONFIG(vulkan) || defined(Q_QDOC)\n"
336"#ifndef VK_NO_PROTOTYPES\n"
337"#define VK_NO_PROTOTYPES\n"
339"#include <vulkan/vulkan.h>\n"
341"#include <QtCore/qscopedpointer.h>\n"
343"QT_BEGIN_NAMESPACE\n"
345"class QVulkanInstance;\n"
346"class QVulkanFunctionsPrivate;\n"
347"class QVulkanDeviceFunctionsPrivate;\n"
349"class Q_GUI_EXPORT QVulkanFunctions\n"
352" ~QVulkanFunctions();\n"
356" Q_DISABLE_COPY(QVulkanFunctions)\n"
357" QVulkanFunctions(QVulkanInstance *inst);\n"
359" QScopedPointer<QVulkanFunctionsPrivate> d_ptr;\n"
360" friend class QVulkanInstance;\n"
363"class Q_GUI_EXPORT QVulkanDeviceFunctions\n"
366" ~QVulkanDeviceFunctions();\n"
370" Q_DISABLE_COPY(QVulkanDeviceFunctions)\n"
371" QVulkanDeviceFunctions(QVulkanInstance *inst, VkDevice device);\n"
373" QScopedPointer<QVulkanDeviceFunctionsPrivate> d_ptr;\n"
374" friend class QVulkanInstance;\n"
379"#endif // QT_CONFIG(vulkan) || defined(Q_QDOC)\n"
381"#endif // QVULKANFUNCTIONS_H\n";
386 const QStringList &coreFunctionsInVersion = versionCommandMapping[version];
387 instCmdStr +=
"#if " + version +
"\n";
388 devCmdStr +=
"#if " + version +
"\n";
390 if (!coreFunctionsInVersion.contains(
c.cmd.name))
393 QString *
dst =
c.deviceLevel ? &devCmdStr : &instCmdStr;
398 instCmdStr +=
"#endif\n";
399 devCmdStr +=
"#endif\n";
403 instCmdStr.toUtf8().constData(),
404 devCmdStr.toUtf8().constData()).toUtf8());
410 const QMap<QString, QStringList> &versionCommandMapping,
420 static const char *
s =
422"#ifndef QVULKANFUNCTIONS_P_H\n"
423"#define QVULKANFUNCTIONS_P_H\n"
429"// This file is not part of the Qt API. It exists purely as an\n"
430"// implementation detail. This header file may change from version to\n"
431"// version without notice, or even be removed.\n"
436"#include \"qvulkanfunctions.h\"\n"
438"QT_BEGIN_NAMESPACE\n"
440"class QVulkanInstance;\n"
442"class QVulkanFunctionsPrivate\n"
445" QVulkanFunctionsPrivate(QVulkanInstance *inst);\n"
447" PFN_vkVoidFunction m_funcs[%d];\n"
450"class QVulkanDeviceFunctionsPrivate\n"
453" QVulkanDeviceFunctionsPrivate(QVulkanInstance *inst, VkDevice device);\n"
455" PFN_vkVoidFunction m_funcs[%d];\n"
460"#endif // QVULKANFUNCTIONS_P_H\n";
462 int devLevelCount = 0;
463 int instLevelCount = 0;
465 const QStringList &coreFunctionsInVersion = versionCommandMapping[version];
467 if (!coreFunctionsInVersion.contains(
c.cmd.name))
483 const QMap<QString, QStringList> &versionCommandMapping,
493 static const char s[] =
495"#include \"qvulkanfunctions_p.h\"\n"
496"#include \"qvulkaninstance.h\"\n"
498"#include <QtCore/private/qoffsetstringarray_p.h>\n"
500"QT_BEGIN_NAMESPACE\n"
502"QVulkanFunctionsPrivate::QVulkanFunctionsPrivate(QVulkanInstance *inst)\n"
504" static constexpr auto funcNames = qOffsetStringArray(\n"
507" static_assert(std::extent_v<decltype(m_funcs)> == size_t(funcNames.count()));\n"
508" for (int i = 0; i < funcNames.count(); ++i) {\n"
509" m_funcs[i] = inst->getInstanceProcAddr(funcNames.at(i));\n"
510" if (i < %d && !m_funcs[i])\n"
511" qWarning(\"QVulkanFunctions: Failed to resolve %%s\", funcNames.at(i));\n"
515"QVulkanDeviceFunctionsPrivate::QVulkanDeviceFunctionsPrivate(QVulkanInstance *inst, VkDevice device)\n"
517" QVulkanFunctions *f = inst->functions();\n"
519" static constexpr auto funcNames = qOffsetStringArray(\n"
522" static_assert(std::extent_v<decltype(m_funcs)> == size_t(funcNames.count()));\n"
523" for (int i = 0; i < funcNames.count(); ++i) {\n"
524" m_funcs[i] = f->vkGetDeviceProcAddr(device, funcNames.at(i));\n"
525" if (i < %d && !m_funcs[i])\n"
526" qWarning(\"QVulkanDeviceFunctions: Failed to resolve %%s\", funcNames.at(i));\n"
538 int vulkan10DevCount = 0;
539 int vulkan10InstCount = 0;
542 const QStringList &coreFunctionsInVersion = versionCommandMapping[version];
543 instCmdWrapperStr +=
"\n#if " + version +
"\n";
544 devCmdWrapperStr +=
"\n#if " + version +
"\n";
546 if (!coreFunctionsInVersion.contains(
c.cmd.name))
549 QString *
dst =
c.deviceLevel ? &devCmdWrapperStr : &instCmdWrapperStr;
550 int *idx =
c.deviceLevel ? &devIdx : &instIdx;
551 *
dst +=
funcSig(
c,
c.deviceLevel ?
"QVulkanDeviceFunctions" :
"QVulkanFunctions");
557 dst =
c.deviceLevel ? &devCmdNamesStr : &instCmdNamesStr;
563 vulkan10InstCount = instIdx;
564 vulkan10DevCount = devIdx;
566 instCmdWrapperStr +=
"#endif\n\n";
567 devCmdWrapperStr +=
"#endif\n\n";
570 if (devCmdNamesStr.size() > 2)
571 devCmdNamesStr.chop(2);
572 if (instCmdNamesStr.size() > 2)
573 instCmdNamesStr.chop(2);
577 instCmdWrapperStr.toUtf8().constData(),
578 instCmdNamesStr.toUtf8().constData(), vulkan10InstCount,
579 devCmdWrapperStr.toUtf8().constData(),
580 devCmdNamesStr.toUtf8().constData(), vulkan10DevCount);
593 qWarning(
"Usage: qvkgen input_vk_xml input_license_header output_base\n"
594 " For example: qvkgen vulkan/vk.xml vulkan/qvulkanfunctions.header vulkan/qvulkanfunctions");
615 if (ignoredFuncs.contains(
commands[
i].cmd.name))
QByteArray get(const QString &fn)
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
QByteArray & replace(qsizetype index, qsizetype len, const char *s, qsizetype alen)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QFILE_MAYBE_NODISCARD bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
void setFileName(const QString &name)
Sets the name of the file.
QString fileName() const override
Returns the name set by setFileName() or to the QFile constructors.
void append(parameter_type t)
\macro QT_RESTRICTED_CAST_FROM_ASCII
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
QString trimmed() const &
QByteArray toUtf8() const &
static QString static QString asprintf(const char *format,...) Q_ATTRIBUTE_FORMAT_PRINTF(1
void setFileName(const QString &fn)
QList< Command > commands() const
QMap< QString, QStringList > versionCommandMapping() const
AudioChannelLayoutTag tag
GLboolean GLboolean GLboolean GLboolean a
[7]
GLsizei const GLubyte * commands
#define qPrintable(string)
#define QStringLiteral(str)
QString funcCall(const VkSpecParser::Command &c, int idx)
bool genVulkanFunctionsH(const QList< VkSpecParser::Command > &commands, const QMap< QString, QStringList > &versionCommandMapping, const QString &licHeaderFn, const QString &outputBase)
bool genVulkanFunctionsPH(const QList< VkSpecParser::Command > &commands, const QMap< QString, QStringList > &versionCommandMapping, const QString &licHeaderFn, const QString &outputBase)
bool genVulkanFunctionsPC(const QList< VkSpecParser::Command > &commands, const QMap< QString, QStringList > &versionCommandMapping, const QString &licHeaderFn, const QString &outputBase)
QString funcSig(const VkSpecParser::Command &c, const char *className=nullptr)
static const QStringList VERSIONS
const char className[16]
[1]
QApplication app(argc, argv)
[0]
QNetworkRequestFactory api
[0]