29 #include <QtCore/qcoreapplication.h>
30 #include <QtCore/qfile.h>
31 #include <QtCore/qfileinfo.h>
32 #include <QtCore/qlist.h>
33 #include <QtCore/qxmlstream.h>
67 void parseFeatureRequire(
const QString &versionDefine);
69 Command parseCommand();
70 TypedName parseParamOrProto(
const QString &
tag);
90 m_versionCommandMapping.
clear();
92 while (!m_reader.
atEnd()) {
105 void VkSpecParser::skip()
108 while (!m_reader.
atEnd()) {
115 void VkSpecParser::parseFeature()
124 api =
attr.value().toString().trimmed();
126 versionName =
attr.value().toString().trimmed();
130 while (!m_reader.
atEnd()) {
136 parseFeatureRequire(versionName);
141 void VkSpecParser::parseFeatureRequire(
const QString &versionDefine)
146 while (!m_reader.
atEnd()) {
153 m_versionCommandMapping[versionDefine].append(
attr.value().toString().trimmed());
159 void VkSpecParser::parseCommands()
164 while (!m_reader.
atEnd()) {
169 const Command
c = parseCommand();
170 if (!
c.cmd.name.isEmpty())
171 m_commands.append(
c);
186 while (!m_reader.
atEnd()) {
193 if (m_reader.
name() == protoStr) {
194 c.cmd = parseParamOrProto(protoStr);
195 }
else if (m_reader.
name() == paramStr) {
196 c.args.append(parseParamOrProto(paramStr));
203 c.deviceLevel =
false;
204 if (!
c.args.isEmpty()) {
210 if (dispatchableDeviceAndChildTypes.contains(
c.args[0].type)
213 c.deviceLevel =
true;
224 while (!m_reader.
atEnd()) {
230 t.name = parseName();
236 if (!
text.isEmpty()) {
238 t.typeSuffix +=
text;
240 if (!
t.type.isEmpty())
251 QString VkSpecParser::parseName()
254 while (!m_reader.
atEnd()) {
267 qPrintable(
c.cmd.name)));
268 if (!
c.args.isEmpty()) {
278 qPrintable(
a.name), qPrintable(
a.typeSuffix));
291 qPrintable(
c.cmd.name),
293 if (!
c.args.isEmpty()) {
324 qWarning(
"Failed to open %s", qPrintable(
fn));
330 m_str +=
"\n// This file is automatically generated by qvkgen. Do not edit.\n";
342 qWarning(
"Failed to write %s", qPrintable(
f.fileName()));
346 static const char *
s =
348 "#ifndef QVULKANFUNCTIONS_H\n"
349 "#define QVULKANFUNCTIONS_H\n"
351 "#include <QtGui/qtguiglobal.h>\n"
353 "#if QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC)\n"
355 "#ifndef VK_NO_PROTOTYPES\n"
356 "#define VK_NO_PROTOTYPES\n"
358 "#include <vulkan/vulkan.h>\n"
360 "#include <QtCore/qscopedpointer.h>\n"
362 "QT_BEGIN_NAMESPACE\n"
364 "class QVulkanInstance;\n"
365 "class QVulkanFunctionsPrivate;\n"
366 "class QVulkanDeviceFunctionsPrivate;\n"
368 "class Q_GUI_EXPORT QVulkanFunctions\n"
371 " ~QVulkanFunctions();\n"
375 " Q_DISABLE_COPY(QVulkanFunctions)\n"
376 " QVulkanFunctions(QVulkanInstance *inst);\n"
378 " QScopedPointer<QVulkanFunctionsPrivate> d_ptr;\n"
379 " friend class QVulkanInstance;\n"
382 "class Q_GUI_EXPORT QVulkanDeviceFunctions\n"
385 " ~QVulkanDeviceFunctions();\n"
389 " Q_DISABLE_COPY(QVulkanDeviceFunctions)\n"
390 " QVulkanDeviceFunctions(QVulkanInstance *inst, VkDevice device);\n"
392 " QScopedPointer<QVulkanDeviceFunctionsPrivate> d_ptr;\n"
393 " friend class QVulkanInstance;\n"
398 "#endif // QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC)\n"
400 "#endif // QVULKANFUNCTIONS_H\n";
406 instCmdStr +=
"#if " +
version +
"\n";
407 devCmdStr +=
"#if " +
version +
"\n";
409 if (!coreFunctionsInVersion.contains(
c.cmd.name))
412 QString *
dst =
c.deviceLevel ? &devCmdStr : &instCmdStr;
417 instCmdStr +=
"#endif\n";
418 devCmdStr +=
"#endif\n";
435 qWarning(
"Failed to write %s", qPrintable(
f.fileName()));
439 static const char *
s =
441 "#ifndef QVULKANFUNCTIONS_P_H\n"
442 "#define QVULKANFUNCTIONS_P_H\n"
448 "// This file is not part of the Qt API. It exists purely as an\n"
449 "// implementation detail. This header file may change from version to\n"
450 "// version without notice, or even be removed.\n"
455 "#include \"qvulkanfunctions.h\"\n"
457 "QT_BEGIN_NAMESPACE\n"
459 "class QVulkanInstance;\n"
461 "class QVulkanFunctionsPrivate\n"
464 " QVulkanFunctionsPrivate(QVulkanInstance *inst);\n"
466 " PFN_vkVoidFunction m_funcs[%d];\n"
469 "class QVulkanDeviceFunctionsPrivate\n"
472 " QVulkanDeviceFunctionsPrivate(QVulkanInstance *inst, VkDevice device);\n"
474 " PFN_vkVoidFunction m_funcs[%d];\n"
479 "#endif // QVULKANFUNCTIONS_P_H\n";
481 int devLevelCount = 0;
482 int instLevelCount = 0;
486 if (!coreFunctionsInVersion.contains(
c.cmd.name))
508 qWarning(
"Failed to write %s", qPrintable(
f.fileName()));
512 static const char s[] =
514 "#include \"qvulkanfunctions_p.h\"\n"
515 "#include \"qvulkaninstance.h\"\n"
517 "#include <QtCore/private/qoffsetstringarray_p.h>\n"
519 "QT_BEGIN_NAMESPACE\n"
521 "QVulkanFunctionsPrivate::QVulkanFunctionsPrivate(QVulkanInstance *inst)\n"
523 " static constexpr auto funcNames = qOffsetStringArray(\n"
526 " static_assert(std::extent_v<decltype(m_funcs)> == size_t(funcNames.count()));\n"
527 " for (int i = 0; i < funcNames.count(); ++i) {\n"
528 " m_funcs[i] = inst->getInstanceProcAddr(funcNames.at(i));\n"
529 " if (i < %d && !m_funcs[i])\n"
530 " qWarning(\"QVulkanFunctions: Failed to resolve %%s\", funcNames.at(i));\n"
534 "QVulkanDeviceFunctionsPrivate::QVulkanDeviceFunctionsPrivate(QVulkanInstance *inst, VkDevice device)\n"
536 " QVulkanFunctions *f = inst->functions();\n"
538 " static constexpr auto funcNames = qOffsetStringArray(\n"
541 " static_assert(std::extent_v<decltype(m_funcs)> == size_t(funcNames.count()));\n"
542 " for (int i = 0; i < funcNames.count(); ++i) {\n"
543 " m_funcs[i] = f->vkGetDeviceProcAddr(device, funcNames.at(i));\n"
544 " if (i < %d && !m_funcs[i])\n"
545 " qWarning(\"QVulkanDeviceFunctions: Failed to resolve %%s\", funcNames.at(i));\n"
549 "QT_END_NAMESPACE\n";
557 int vulkan10DevCount = 0;
558 int vulkan10InstCount = 0;
562 instCmdWrapperStr +=
"\n#if " +
version +
"\n";
563 devCmdWrapperStr +=
"\n#if " +
version +
"\n";
565 if (!coreFunctionsInVersion.contains(
c.cmd.name))
568 QString *
dst =
c.deviceLevel ? &devCmdWrapperStr : &instCmdWrapperStr;
569 int *
idx =
c.deviceLevel ? &devIdx : &instIdx;
570 *
dst +=
funcSig(
c,
c.deviceLevel ?
"QVulkanDeviceFunctions" :
"QVulkanFunctions");
576 dst =
c.deviceLevel ? &devCmdNamesStr : &instCmdNamesStr;
582 vulkan10InstCount = instIdx;
583 vulkan10DevCount = devIdx;
585 instCmdWrapperStr +=
"#endif\n\n";
586 devCmdWrapperStr +=
"#endif\n\n";
589 if (devCmdNamesStr.
count() > 2)
590 devCmdNamesStr = devCmdNamesStr.
left(devCmdNamesStr.
count() - 2);
591 if (instCmdNamesStr.
count() > 2)
592 instCmdNamesStr = instCmdNamesStr.
left(instCmdNamesStr.
count() - 2);
606 int main(
int argc,
char **argv)
612 qWarning(
"Usage: qvkgen input_vk_xml input_license_header output_base\n"
613 " For example: qvkgen vulkan/vk.xml vulkan/qvulkanfunctions.header vulkan/qvulkanfunctions");
634 if (ignoredFuncs.contains(
commands[
i].cmd.name))
small capitals from c petite p scientific i
[1]
QByteArray get(const QString &fn)
The QByteArray class provides an array of bytes.
const char * constData() const noexcept
bool isEmpty() const noexcept
QByteArray & replace(qsizetype index, qsizetype len, const char *s, qsizetype alen)
The QCoreApplication class provides an event loop for Qt applications without UI.
The QFile class provides an interface for reading from and writing to files.
bool open(OpenMode flags) override
void setFileName(const QString &name)
QString fileName() const override
The QString class provides a Unicode character string.
static QString fromUtf8(QByteArrayView utf8)
QString left(qsizetype n) const
QByteArray toUtf8() const &
static QString static QString asprintf(const char *format,...) Q_ATTRIBUTE_FORMAT_PRINTF(1
The QStringList class provides a list of strings.
QStringView trimmed() const noexcept
The QXmlStreamAttribute class represents a single XML attribute.
The QXmlStreamReader class provides a fast parser for reading well-formed XML via a simple streaming ...
QXmlStreamAttributes attributes() const
bool isStartElement() const
bool isEndElement() const
void setDevice(QIODevice *device)
QList< Command > commands() const
void setFileName(const QString &fn)
QMap< QString, QStringList > versionCommandMapping() const
GLsizei const GLubyte * commands
[10]
GLboolean GLboolean GLboolean GLboolean a
[7]
#define QStringLiteral(str)
int main(int argc, char **argv)
[1]
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)
const char className[16]
[1]
QApplication app(argc, argv)
[0]
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
XmlOutput::xml_output tag(const QString &name)
XmlOutput::xml_output attr(const QString &name, const QString &value)