mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-27 08:05:42 +00:00
Allow for configuring multiple SPIR-V disassemblers, detect known tools
* Initially add support for spirv-cross and spirv-dis. * When possible we'll auto-detect the tools in path or in the build's plugins folder. Otherwise the user can add it and add their executable path. * We still use the first disassembler for editing - in future it would be good to allow selecting the disassembler at edit time (as well as allowing multiple compilers).
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QStandardPaths>
|
||||
#include "Code/QRDUtils.h"
|
||||
#include "Styles/StyleData.h"
|
||||
#include "QRDInterface.h"
|
||||
@@ -308,6 +309,66 @@ bool PersistantConfig::Load(const rdcstr &filename)
|
||||
RemoteHosts.insert(0, host);
|
||||
}
|
||||
|
||||
bool tools[arraydim<KnownSPIRVTool>()] = {};
|
||||
|
||||
// see which known tools are registered
|
||||
for(const SPIRVDisassembler &dis : SPIRVDisassemblers)
|
||||
{
|
||||
// if it's declared
|
||||
if(dis.tool != KnownSPIRVTool::Unknown)
|
||||
tools[(size_t)dis.tool] = true;
|
||||
|
||||
for(KnownSPIRVTool tool : values<KnownSPIRVTool>())
|
||||
{
|
||||
if(QString(dis.executable).contains(ToolExecutable(tool)))
|
||||
tools[(size_t)tool] = true;
|
||||
}
|
||||
}
|
||||
|
||||
for(KnownSPIRVTool tool : values<KnownSPIRVTool>())
|
||||
{
|
||||
if(tool == KnownSPIRVTool::Unknown || tools[(size_t)tool])
|
||||
continue;
|
||||
|
||||
QString exe = ToolExecutable(tool);
|
||||
|
||||
if(exe.isEmpty())
|
||||
continue;
|
||||
|
||||
// try to find the tool in PATH
|
||||
QString path = QStandardPaths::findExecutable(exe);
|
||||
|
||||
if(!path.isEmpty())
|
||||
{
|
||||
SPIRVDisassembler dis;
|
||||
dis.name = ToQStr(tool);
|
||||
// we store just the base name, so when we launch the process it will always find it in PATH,
|
||||
// rather than baking in the current PATH result.
|
||||
dis.executable = exe;
|
||||
dis.tool = tool;
|
||||
|
||||
SPIRVDisassemblers.push_back(dis);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// try to find it in our plugins folder
|
||||
path = QStandardPaths::findExecutable(
|
||||
exe, {QDir(QApplication::applicationDirPath()).absoluteFilePath(lit("plugins/spirv/"))});
|
||||
|
||||
if(!path.isEmpty())
|
||||
{
|
||||
SPIRVDisassembler dis;
|
||||
dis.name = ToQStr(tool);
|
||||
dis.executable = path;
|
||||
dis.tool = tool;
|
||||
|
||||
SPIRVDisassemblers.push_back(dis);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -393,6 +454,8 @@ rdcstr PersistantConfig::GetConfigSetting(const rdcstr &name)
|
||||
SPIRVDisassembler::SPIRVDisassembler(const QVariant &var)
|
||||
{
|
||||
QVariantMap map = var.toMap();
|
||||
if(map.contains(lit("tool")))
|
||||
tool = (KnownSPIRVTool)map[lit("tool")].toUInt();
|
||||
if(map.contains(lit("name")))
|
||||
name = map[lit("name")].toString();
|
||||
if(map.contains(lit("executable")))
|
||||
@@ -405,6 +468,7 @@ SPIRVDisassembler::operator QVariant() const
|
||||
{
|
||||
QVariantMap map;
|
||||
|
||||
map[lit("tool")] = (uint32_t)tool;
|
||||
map[lit("name")] = name;
|
||||
map[lit("executable")] = executable;
|
||||
map[lit("args")] = args;
|
||||
|
||||
@@ -28,18 +28,55 @@
|
||||
#include "QRDInterface.h"
|
||||
#include "RemoteHost.h"
|
||||
|
||||
DOCUMENT(R"(Identifies a particular known SPIR-V tool used for disassembly.
|
||||
|
||||
.. data:: Unknown
|
||||
|
||||
Corresponds to no known tool.
|
||||
|
||||
.. data:: SPIRV_Cross
|
||||
|
||||
`SPIRV-Cross <https://github.com/KhronosGroup/SPIRV-Cross>`_.
|
||||
|
||||
.. data:: spirv_dis
|
||||
|
||||
`spirv-dis from SPIRV-Tools <https://github.com/KhronosGroup/SPIRV-Tools>`_.
|
||||
)");
|
||||
enum class KnownSPIRVTool : uint32_t
|
||||
{
|
||||
Unknown,
|
||||
First = Unknown,
|
||||
SPIRV_Cross,
|
||||
spirv_dis,
|
||||
Count,
|
||||
};
|
||||
|
||||
ITERABLE_OPERATORS(KnownSPIRVTool);
|
||||
|
||||
inline rdcstr ToolExecutable(KnownSPIRVTool tool)
|
||||
{
|
||||
if(tool == KnownSPIRVTool::SPIRV_Cross)
|
||||
return "spirv-cross";
|
||||
else if(tool == KnownSPIRVTool::spirv_dis)
|
||||
return "spirv-dis";
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
DOCUMENT("Describes an external program that can be used to disassemble SPIR-V.");
|
||||
struct SPIRVDisassembler
|
||||
{
|
||||
DOCUMENT("");
|
||||
SPIRVDisassembler() {}
|
||||
SPIRVDisassembler() = default;
|
||||
VARIANT_CAST(SPIRVDisassembler);
|
||||
bool operator==(const SPIRVDisassembler &o) const
|
||||
{
|
||||
return name == o.name && executable == o.executable && args == o.args;
|
||||
return tool == o.tool && name == o.name && executable == o.executable && args == o.args;
|
||||
}
|
||||
bool operator<(const SPIRVDisassembler &o) const
|
||||
{
|
||||
if(tool != o.tool)
|
||||
return tool < o.tool;
|
||||
if(name != o.name)
|
||||
return name < o.name;
|
||||
if(executable != o.executable)
|
||||
@@ -48,6 +85,8 @@ struct SPIRVDisassembler
|
||||
return args < o.args;
|
||||
return false;
|
||||
}
|
||||
DOCUMENT("The :class:`KnownSPIRVTool` identifying which known tool this disassembler is.");
|
||||
KnownSPIRVTool tool = KnownSPIRVTool::Unknown;
|
||||
DOCUMENT("The human-readable name of the program.");
|
||||
rdcstr name;
|
||||
DOCUMENT("The path to the executable to run for this program.");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#/******************************************************************************
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016-2018 Baldur Karlsson
|
||||
@@ -27,6 +27,18 @@
|
||||
#include "Code/QRDUtils.h"
|
||||
#include "QRDInterface.h"
|
||||
|
||||
template <>
|
||||
std::string DoStringise(const KnownSPIRVTool &el)
|
||||
{
|
||||
BEGIN_ENUM_STRINGISE(KnownSPIRVTool);
|
||||
{
|
||||
STRINGISE_ENUM_CLASS_NAMED(Unknown, "Custom Tool");
|
||||
STRINGISE_ENUM_CLASS_NAMED(SPIRV_Cross, "SPIRV-Cross");
|
||||
STRINGISE_ENUM_CLASS_NAMED(spirv_dis, "spirv-dis");
|
||||
}
|
||||
END_ENUM_STRINGISE();
|
||||
}
|
||||
|
||||
rdcstr SPIRVDisassembler::DisassembleShader(QWidget *window, const ShaderReflection *shaderDetails) const
|
||||
{
|
||||
if(executable.isEmpty())
|
||||
@@ -50,7 +62,20 @@ rdcstr SPIRVDisassembler::DisassembleShader(QWidget *window, const ShaderReflect
|
||||
return "";
|
||||
}
|
||||
|
||||
if(!QString(args).contains(lit("{spv_bin}")))
|
||||
QString programArguments = args;
|
||||
|
||||
switch(tool)
|
||||
{
|
||||
case KnownSPIRVTool::SPIRV_Cross:
|
||||
programArguments = lit("--output {spv_disas} {spv_bin} --vulkan-semantics");
|
||||
break;
|
||||
case KnownSPIRVTool::spirv_dis:
|
||||
programArguments = lit("--no-color -o {spv_disas} {spv_bin}");
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if(!programArguments.contains(lit("{spv_bin}")))
|
||||
{
|
||||
RDDialog::critical(
|
||||
window, QApplication::translate("SPIRVDisassembler", "Wrongly configured disassembler"),
|
||||
@@ -62,10 +87,10 @@ rdcstr SPIRVDisassembler::DisassembleShader(QWidget *window, const ShaderReflect
|
||||
|
||||
QString glsl;
|
||||
|
||||
LambdaThread *thread = new LambdaThread([this, window, &glsl, spv_bin_file]() {
|
||||
LambdaThread *thread = new LambdaThread([this, window, &glsl, programArguments, spv_bin_file]() {
|
||||
QString spv_disas_file = QDir(QDir::tempPath()).absoluteFilePath(lit("spv_disas.txt"));
|
||||
|
||||
QString expandedargs = args;
|
||||
QString expandedargs = programArguments;
|
||||
|
||||
bool writesToFile = expandedargs.contains(lit("{spv_disas}"));
|
||||
|
||||
|
||||
@@ -30,6 +30,61 @@
|
||||
#include "CaptureDialog.h"
|
||||
#include "ui_SettingsDialog.h"
|
||||
|
||||
class KnownSPIRVToolDelegate : public QStyledItemDelegate
|
||||
{
|
||||
public:
|
||||
explicit KnownSPIRVToolDelegate(QWidget *parent = NULL) : QStyledItemDelegate(parent) {}
|
||||
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override
|
||||
{
|
||||
QComboBox *editor = new QComboBox(parent);
|
||||
|
||||
editor->setEditable(true);
|
||||
editor->setInsertPolicy(QComboBox::NoInsert);
|
||||
|
||||
QStringList items;
|
||||
for(KnownSPIRVTool tool : values<KnownSPIRVTool>())
|
||||
items << ToQStr(tool);
|
||||
editor->addItems(items);
|
||||
|
||||
return editor;
|
||||
}
|
||||
|
||||
void setEditorData(QWidget *editor, const QModelIndex &index) const override
|
||||
{
|
||||
QComboBox *comboEditor = qobject_cast<QComboBox *>(editor);
|
||||
if(comboEditor)
|
||||
{
|
||||
QString editData = index.data(Qt::EditRole).toString();
|
||||
|
||||
int idx = comboEditor->findText(editData);
|
||||
|
||||
if(idx >= 0)
|
||||
comboEditor->setCurrentIndex(idx);
|
||||
else
|
||||
comboEditor->setCurrentText(index.data(Qt::EditRole).toString());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
QStyledItemDelegate::setEditorData(editor, index);
|
||||
}
|
||||
|
||||
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
|
||||
{
|
||||
QComboBox *comboEditor = qobject_cast<QComboBox *>(editor);
|
||||
if(comboEditor)
|
||||
{
|
||||
model->setData(index, comboEditor->currentText(), Qt::EditRole);
|
||||
return;
|
||||
}
|
||||
|
||||
QStyledItemDelegate::setModelData(editor, model, index);
|
||||
}
|
||||
|
||||
private slots:
|
||||
};
|
||||
|
||||
SettingsDialog::SettingsDialog(ICaptureContext &ctx, QWidget *parent)
|
||||
: QDialog(parent), ui(new Ui::SettingsDialog), m_Ctx(ctx)
|
||||
{
|
||||
@@ -79,11 +134,26 @@ SettingsDialog::SettingsDialog(ICaptureContext &ctx, QWidget *parent)
|
||||
ui->saveDirectory->setText(m_Ctx.Config().DefaultCaptureSaveDirectory);
|
||||
ui->tempDirectory->setText(m_Ctx.Config().TemporaryCaptureDirectory);
|
||||
|
||||
if(!m_Ctx.Config().SPIRVDisassemblers.isEmpty())
|
||||
{
|
||||
ui->externalDisassemblerArgs->setText(m_Ctx.Config().SPIRVDisassemblers[0].args);
|
||||
ui->externalDisassemblePath->setText(m_Ctx.Config().SPIRVDisassemblers[0].executable);
|
||||
}
|
||||
ui->disassemblers->setColumnCount(3);
|
||||
ui->disassemblers->setHorizontalHeaderLabels(QStringList() << tr("Tool") << tr("Executable")
|
||||
<< tr("Arguments"));
|
||||
|
||||
ui->disassemblers->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Interactive);
|
||||
ui->disassemblers->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Interactive);
|
||||
ui->disassemblers->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
|
||||
|
||||
for(const SPIRVDisassembler &disasm : m_Ctx.Config().SPIRVDisassemblers)
|
||||
addDisassembler(disasm);
|
||||
|
||||
ui->disassemblers->horizontalHeader()->resizeSection(0, 100);
|
||||
|
||||
ui->disassemblers->verticalHeader()->setSectionsMovable(true);
|
||||
ui->disassemblers->verticalHeader()->setMinimumWidth(20);
|
||||
|
||||
ui->disassemblers->setItemDelegateForColumn(0, new KnownSPIRVToolDelegate(this));
|
||||
|
||||
ui->deleteDisasm->setEnabled(false);
|
||||
|
||||
ui->Android_SDKPath->setText(m_Ctx.Config().Android_SDKPath);
|
||||
ui->Android_JDKPath->setText(m_Ctx.Config().Android_JDKPath);
|
||||
ui->Android_MaxConnectTimeout->setValue(m_Ctx.Config().Android_MaxConnectTimeout);
|
||||
@@ -127,6 +197,8 @@ SettingsDialog::SettingsDialog(ICaptureContext &ctx, QWidget *parent)
|
||||
|
||||
m_Init = false;
|
||||
|
||||
QObject::connect(ui->disassemblers->verticalHeader(), &QHeaderView::sectionMoved, this,
|
||||
&SettingsDialog::disassemblers_rowMoved);
|
||||
QObject::connect(ui->Formatter_MinFigures, OverloadedSlot<int>::of(&QSpinBox::valueChanged), this,
|
||||
&SettingsDialog::formatter_valueChanged);
|
||||
QObject::connect(ui->Formatter_MaxFigures, OverloadedSlot<int>::of(&QSpinBox::valueChanged), this,
|
||||
@@ -302,39 +374,144 @@ void SettingsDialog::on_ShaderViewer_FriendlyNaming_toggled(bool checked)
|
||||
m_Ctx.Config().Save();
|
||||
}
|
||||
|
||||
void SettingsDialog::on_browseExtDisasemble_clicked()
|
||||
void SettingsDialog::addDisassembler(const SPIRVDisassembler &disasm)
|
||||
{
|
||||
QString filePath = RDDialog::getExecutableFileName(this, tr("Locate SPIR-V disassembler"));
|
||||
// prevent calling cellChanged
|
||||
m_AddingDisassembler = true;
|
||||
|
||||
if(!filePath.isEmpty())
|
||||
int row = ui->disassemblers->rowCount();
|
||||
ui->disassemblers->insertRow(row);
|
||||
|
||||
ui->disassemblers->setVerticalHeaderItem(row, new QTableWidgetItem(QString()));
|
||||
|
||||
ui->disassemblers->setItem(row, 0, new QTableWidgetItem(disasm.name));
|
||||
ui->disassemblers->setItem(row, 1, new QTableWidgetItem(disasm.executable));
|
||||
|
||||
QTableWidgetItem *item =
|
||||
new QTableWidgetItem(disasm.tool == KnownSPIRVTool::Unknown ? disasm.args : tr("Automatic"));
|
||||
ui->disassemblers->setItem(row, 2, item);
|
||||
|
||||
// make arguments non-editable for built-in tools
|
||||
if(disasm.tool != KnownSPIRVTool::Unknown)
|
||||
{
|
||||
ui->externalDisassemblePath->setText(filePath);
|
||||
on_externalDisassemblePath_textEdited(filePath);
|
||||
Qt::ItemFlags flags = item->flags() & ~Qt::ItemIsEditable;
|
||||
item->setFlags(flags);
|
||||
}
|
||||
|
||||
m_AddingDisassembler = false;
|
||||
}
|
||||
|
||||
void SettingsDialog::on_externalDisassemblePath_textEdited(const QString &path)
|
||||
void SettingsDialog::on_addDisasm_clicked()
|
||||
{
|
||||
if(m_Ctx.Config().SPIRVDisassemblers.isEmpty())
|
||||
{
|
||||
m_Ctx.Config().SPIRVDisassemblers.push_back(SPIRVDisassembler());
|
||||
m_Ctx.Config().SPIRVDisassemblers.back().name = lit("Unknown");
|
||||
}
|
||||
SPIRVDisassembler disasm;
|
||||
disasm.name = tr("Custom Tool");
|
||||
disasm.executable = lit("path/to/executable");
|
||||
disasm.args = lit("--input {spv_bin} --output {spv_disasm}");
|
||||
m_Ctx.Config().SPIRVDisassemblers.push_back(disasm);
|
||||
|
||||
m_Ctx.Config().SPIRVDisassemblers.back().executable = path;
|
||||
addDisassembler(disasm);
|
||||
|
||||
m_Ctx.Config().Save();
|
||||
}
|
||||
|
||||
void SettingsDialog::on_externalDisassemblerArgs_textEdited(const QString &args)
|
||||
void SettingsDialog::on_deleteDisasm_clicked()
|
||||
{
|
||||
if(m_Ctx.Config().SPIRVDisassemblers.isEmpty())
|
||||
int row = -1;
|
||||
|
||||
QModelIndexList selected = ui->disassemblers->selectionModel()->selectedRows();
|
||||
|
||||
if(!selected.isEmpty())
|
||||
row = selected[0].row();
|
||||
|
||||
if(row < 0 || row >= m_Ctx.Config().SPIRVDisassemblers.count())
|
||||
return;
|
||||
|
||||
const SPIRVDisassembler &disasm = m_Ctx.Config().SPIRVDisassemblers[row];
|
||||
|
||||
QMessageBox::StandardButton res = RDDialog::question(
|
||||
this, tr("Are you sure?"), tr("Are you sure you want to delete '%1'?").arg(disasm.name),
|
||||
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
|
||||
|
||||
if(res == QMessageBox::Yes)
|
||||
{
|
||||
m_Ctx.Config().SPIRVDisassemblers.push_back(SPIRVDisassembler());
|
||||
m_Ctx.Config().SPIRVDisassemblers.back().name = lit("Unknown");
|
||||
ui->disassemblers->removeRow(row);
|
||||
m_Ctx.Config().SPIRVDisassemblers.erase(row);
|
||||
|
||||
m_Ctx.Config().Save();
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::on_disassemblers_itemSelectionChanged()
|
||||
{
|
||||
ui->deleteDisasm->setEnabled(!ui->disassemblers->selectionModel()->selectedIndexes().empty());
|
||||
}
|
||||
|
||||
void SettingsDialog::on_disassemblers_cellChanged(int row, int column)
|
||||
{
|
||||
if(m_AddingDisassembler || row < 0 || row >= m_Ctx.Config().SPIRVDisassemblers.count())
|
||||
return;
|
||||
|
||||
SPIRVDisassembler &disasm = m_Ctx.Config().SPIRVDisassemblers[row];
|
||||
|
||||
QString cellData = ui->disassemblers->item(row, column)->text();
|
||||
|
||||
if(column == 0)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
for(KnownSPIRVTool tool : values<KnownSPIRVTool>())
|
||||
{
|
||||
if(ToQStr(tool) == cellData)
|
||||
{
|
||||
disasm.tool = tool;
|
||||
disasm.name = cellData;
|
||||
found = true;
|
||||
|
||||
// make arguments non-editable
|
||||
Qt::ItemFlags flags = ui->disassemblers->item(row, 2)->flags() & ~Qt::ItemIsEditable;
|
||||
ui->disassemblers->item(row, 2)->setFlags(flags);
|
||||
}
|
||||
}
|
||||
|
||||
if(!found)
|
||||
{
|
||||
disasm.tool = KnownSPIRVTool::Unknown;
|
||||
disasm.name = cellData;
|
||||
|
||||
// make arguments editable
|
||||
Qt::ItemFlags flags = ui->disassemblers->item(row, 2)->flags() | Qt::ItemIsEditable;
|
||||
ui->disassemblers->item(row, 2)->setFlags(flags);
|
||||
}
|
||||
}
|
||||
else if(column == 1)
|
||||
{
|
||||
disasm.executable = cellData;
|
||||
}
|
||||
else if(column == 2)
|
||||
{
|
||||
disasm.args = cellData;
|
||||
}
|
||||
|
||||
m_Ctx.Config().SPIRVDisassemblers.back().args = args;
|
||||
m_Ctx.Config().Save();
|
||||
}
|
||||
|
||||
void SettingsDialog::on_disassemblers_keyPress(QKeyEvent *event)
|
||||
{
|
||||
if(event->key() == Qt::Key_Delete)
|
||||
{
|
||||
ui->deleteDisasm->click();
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::disassemblers_rowMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex)
|
||||
{
|
||||
if(oldVisualIndex < 0 || oldVisualIndex >= m_Ctx.Config().SPIRVDisassemblers.count() ||
|
||||
newVisualIndex < 0 || newVisualIndex >= m_Ctx.Config().SPIRVDisassemblers.count())
|
||||
return;
|
||||
|
||||
SPIRVDisassembler disasm = m_Ctx.Config().SPIRVDisassemblers.at(oldVisualIndex);
|
||||
m_Ctx.Config().SPIRVDisassemblers.erase(oldVisualIndex);
|
||||
m_Ctx.Config().SPIRVDisassemblers.insert(newVisualIndex, disasm);
|
||||
|
||||
m_Ctx.Config().Save();
|
||||
}
|
||||
|
||||
@@ -70,9 +70,12 @@ private slots:
|
||||
// shader viewer
|
||||
void on_ShaderViewer_FriendlyNaming_toggled(bool checked);
|
||||
|
||||
void on_browseExtDisasemble_clicked();
|
||||
void on_externalDisassemblePath_textEdited(const QString &path);
|
||||
void on_externalDisassemblerArgs_textEdited(const QString &args);
|
||||
void on_addDisasm_clicked();
|
||||
void on_deleteDisasm_clicked();
|
||||
void on_disassemblers_itemSelectionChanged();
|
||||
void on_disassemblers_cellChanged(int row, int column);
|
||||
void on_disassemblers_keyPress(QKeyEvent *event);
|
||||
void disassemblers_rowMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex);
|
||||
|
||||
// event browser
|
||||
void on_EventBrowser_TimeUnit_currentIndexChanged(int index);
|
||||
@@ -100,6 +103,9 @@ private slots:
|
||||
private:
|
||||
Ui::SettingsDialog *ui;
|
||||
|
||||
void addDisassembler(const SPIRVDisassembler &disasm);
|
||||
|
||||
ICaptureContext &m_Ctx;
|
||||
bool m_Init = false;
|
||||
bool m_AddingDisassembler = false;
|
||||
};
|
||||
|
||||
@@ -638,62 +638,17 @@ This option overrides that and will always replay locally if the local context i
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Vulkan Shaders</string>
|
||||
<string>Vulkan Disassemblers</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="browseExtDisasemble">
|
||||
<property name="toolTip">
|
||||
<string>Choose the executable file to invoke every time a shader needs to be disassembled</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Browse</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string>External Disassembler executable</string>
|
||||
<string><html><head/><body><p>Available SPIR-V Disassemblers. Click items to edit, drag row header to change priority.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLineEdit" name="externalDisassemblePath">
|
||||
<property name="toolTip">
|
||||
<string>Choose the executable file to invoke every time a shader needs to be disassembled</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_17">
|
||||
<property name="text">
|
||||
<string>External Disassembler command line arguments</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLineEdit" name="externalDisassemblerArgs">
|
||||
<property name="toolTip">
|
||||
<string>The command line arguments to the executable.
|
||||
|
||||
The {spv_bin} and {spv_disas} tags indicate the (temporary) path to the SPIR-V binary file, and the expected SPIR-V disassembled file to create.
|
||||
|
||||
If {spv_disas} is not used, the tool is expected to output the disassembly on stdout.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_18">
|
||||
<property name="text">
|
||||
<string>NOTE: Use the {spv_bin} and {spv_disas} tags to indicate to the external disassembler the input SPIR-V binary and the output SPIR-V disassembly respectively.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<item row="3" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@@ -706,6 +661,65 @@ If {spv_disas} is not used, the tool is expected to output the disassembly on st
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="RDTableWidget" name="disassemblers">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked</set>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="textElideMode">
|
||||
<enum>Qt::ElideMiddle</enum>
|
||||
</property>
|
||||
<property name="cornerButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderHighlightSections">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderHighlightSections">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="addDisasm">
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="deleteDisasm">
|
||||
<property name="text">
|
||||
<string>Delete</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -1082,6 +1096,13 @@ This can enable debugging of Vulkan apps that don't already contain the layer.</
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>RDTableWidget</class>
|
||||
<extends>QTableWidget</extends>
|
||||
<header>Widgets/Extended/RDTableWidget.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
||||
Reference in New Issue
Block a user