mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-08 07:41:12 +00:00
Add functionality to reset an edited shader to original. Closes #2334
* We also add the ability to toggle on/off the replacement being active without needing to intentionally add a compile error (and this also makes it more explicitly clear when the shader replacement is enabled or not. This could be useful for quick A/B testing between the edited version and the original.
This commit is contained in:
@@ -42,7 +42,7 @@ Using the built-in shader editor
|
||||
|
||||
When you have launched the shader editor, the main window will be filled with the source of your shader. In here you can make edits and changes with the basic controls and syntax highlighting available with the Scintilla editor.
|
||||
|
||||
To compile the shader and apply your changes, either click the refresh button in the toolbar or press :kbd:`F5`. This will compile the shader and apply it, any warnings and errors will be added to the errors panel below the main source.
|
||||
To compile the shader and apply your changes, either click the Apply changes button in the toolbar or press :kbd:`F5`. This will compile the shader and apply it, any warnings and errors will be added to the errors panel below the main source.
|
||||
|
||||
You can choose the tool used to compile in the lower section, as well as configure any parameters to it. See above for more information about shader processing tools.
|
||||
|
||||
|
||||
@@ -1973,14 +1973,14 @@ void CaptureContext::LoadEdits(const QString &data)
|
||||
ApplyShaderEdit(viewer, id, stage, shaderEncoding, flags, entryFunc, shaderBytes);
|
||||
};
|
||||
|
||||
auto replaceCloseCallback = [this](ICaptureContext *ctx, IShaderViewer *view, ResourceId id) {
|
||||
auto replaceRevertCallback = [this](ICaptureContext *ctx, IShaderViewer *view, ResourceId id) {
|
||||
RevertShaderEdit(view, id);
|
||||
};
|
||||
|
||||
for(QVariant e : editors)
|
||||
{
|
||||
ShaderViewer *edit =
|
||||
ShaderViewer::LoadEditor(*this, e.toMap(), replaceSaveCallback, replaceCloseCallback,
|
||||
ShaderViewer::LoadEditor(*this, e.toMap(), replaceSaveCallback, replaceRevertCallback,
|
||||
[this](ShaderViewer *view, bool closed) {
|
||||
SetModification(CaptureModifications::EditedShaders);
|
||||
if(closed)
|
||||
@@ -2457,7 +2457,7 @@ IShaderViewer *CaptureContext::EditShader(ResourceId id, ShaderStage stage,
|
||||
const rdcstr &entryPoint, const rdcstrpairs &files,
|
||||
ShaderEncoding shaderEncoding, ShaderCompileFlags flags,
|
||||
IShaderViewer::SaveCallback saveCallback,
|
||||
IShaderViewer::CloseCallback closeCallback)
|
||||
IShaderViewer::RevertCallback revertCallback)
|
||||
{
|
||||
ShaderViewer *viewer = NULL;
|
||||
|
||||
@@ -2474,16 +2474,16 @@ IShaderViewer *CaptureContext::EditShader(ResourceId id, ShaderStage stage,
|
||||
saveCallback(ctx, viewer, id, stage, shaderEncoding, flags, entryFunc, shaderBytes);
|
||||
};
|
||||
|
||||
auto replaceCloseCallback = [this, closeCallback](ICaptureContext *ctx, IShaderViewer *view,
|
||||
ResourceId id) {
|
||||
auto replaceRevertCallback = [this, revertCallback](ICaptureContext *ctx, IShaderViewer *view,
|
||||
ResourceId id) {
|
||||
RevertShaderEdit(view, id);
|
||||
|
||||
if(closeCallback)
|
||||
closeCallback(ctx, view, id);
|
||||
if(revertCallback)
|
||||
revertCallback(ctx, view, id);
|
||||
};
|
||||
|
||||
viewer = ShaderViewer::EditShader(*this, id, stage, entryPoint, files, shaderEncoding, flags,
|
||||
replaceSaveCallback, replaceCloseCallback,
|
||||
replaceSaveCallback, replaceRevertCallback,
|
||||
[this](ShaderViewer *view, bool closed) {
|
||||
SetModification(CaptureModifications::EditedShaders);
|
||||
if(closed)
|
||||
@@ -2497,7 +2497,7 @@ IShaderViewer *CaptureContext::EditShader(ResourceId id, ShaderStage stage,
|
||||
else
|
||||
{
|
||||
viewer = ShaderViewer::EditShader(*this, id, stage, entryPoint, files, shaderEncoding, flags,
|
||||
saveCallback, closeCallback, NULL, m_MainWindow->Widget());
|
||||
saveCallback, revertCallback, NULL, m_MainWindow->Widget());
|
||||
}
|
||||
|
||||
return viewer;
|
||||
@@ -2546,12 +2546,18 @@ void CaptureContext::ApplyShaderEdit(IShaderViewer *viewer, ResourceId id, Shade
|
||||
|
||||
void CaptureContext::RevertShaderEdit(IShaderViewer *viewer, ResourceId id)
|
||||
{
|
||||
QPointer<QObject> ptr(viewer->Widget());
|
||||
|
||||
// remove the replacement on close (we could make this more sophisticated if there
|
||||
// was a place to control replaced resources/shaders).
|
||||
Replay().AsyncInvoke([this, id](IReplayController *r) {
|
||||
Replay().AsyncInvoke([this, viewer, id, ptr](IReplayController *r) {
|
||||
if(IsCaptureLoaded())
|
||||
r->RemoveReplacement(id);
|
||||
GUIInvoke::call(GetMainWindow()->Widget(), [this, id] { UnregisterReplacement(id); });
|
||||
GUIInvoke::call(GetMainWindow()->Widget(), [this, viewer, id, ptr] {
|
||||
UnregisterReplacement(id);
|
||||
if(ptr)
|
||||
viewer->ShowErrors(rdcstr());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -245,7 +245,7 @@ public:
|
||||
IShaderViewer *EditShader(ResourceId id, ShaderStage stage, const rdcstr &entryPoint,
|
||||
const rdcstrpairs &files, ShaderEncoding shaderEncoding,
|
||||
ShaderCompileFlags flags, IShaderViewer::SaveCallback saveCallback,
|
||||
IShaderViewer::CloseCallback closeCallback) override;
|
||||
IShaderViewer::RevertCallback revertCallback) override;
|
||||
|
||||
void ApplyShaderEdit(IShaderViewer *viewer, ResourceId id, ShaderStage stage,
|
||||
ShaderEncoding shaderEncoding, ShaderCompileFlags flags,
|
||||
|
||||
@@ -1096,9 +1096,9 @@ DOCUMENT(R"(A shader window used for viewing, editing, or debugging.
|
||||
:param bytes source: The byte buffer containing the source - may just be text depending on the
|
||||
encoding.
|
||||
|
||||
.. function:: CloseCallback(context)
|
||||
.. function:: RevertCallback(context)
|
||||
|
||||
Not a member function - the signature for any ``CloseCallback`` callbacks.
|
||||
Not a member function - the signature for any ``RevertCallback`` callbacks.
|
||||
|
||||
Called whenever a shader viewer that was open for editing is closed.
|
||||
|
||||
@@ -1111,7 +1111,7 @@ struct IShaderViewer
|
||||
typedef std::function<void(ICaptureContext *, IShaderViewer *, ResourceId, ShaderStage,
|
||||
ShaderEncoding, ShaderCompileFlags, rdcstr, bytebuf)>
|
||||
SaveCallback;
|
||||
typedef std::function<void(ICaptureContext *, IShaderViewer *, ResourceId)> CloseCallback;
|
||||
typedef std::function<void(ICaptureContext *, IShaderViewer *, ResourceId)> RevertCallback;
|
||||
|
||||
DOCUMENT(R"(Retrieves the PySide2 QWidget for this :class:`ShaderViewer` if PySide2 is available, or otherwise
|
||||
returns a unique opaque pointer that can be passed back to any RenderDoc functions expecting a
|
||||
@@ -2483,8 +2483,8 @@ place if needed.
|
||||
:param renderdoc.ShaderCompileFlags flags: The flags originally used to compile the shader.
|
||||
:param ShaderViewer.SaveCallback saveCallback: The callback function to call when a save/update is
|
||||
triggered.
|
||||
:param ShaderViewer.CloseCallback closeCallback: The callback function to call when the shader
|
||||
viewer is closed.
|
||||
:param ShaderViewer.RevertCallback revertCallback: The callback function to call when the shader
|
||||
is to be reverted - either by user request or because the shader viewer was closed.
|
||||
:return: The new :class:`ShaderViewer` window opened but not shown for editing.
|
||||
:rtype: ShaderViewer
|
||||
)");
|
||||
@@ -2492,7 +2492,7 @@ place if needed.
|
||||
const rdcstrpairs &files, ShaderEncoding shaderEncoding,
|
||||
ShaderCompileFlags flags,
|
||||
IShaderViewer::SaveCallback saveCallback,
|
||||
IShaderViewer::CloseCallback closeCallback) = 0;
|
||||
IShaderViewer::RevertCallback revertCallback) = 0;
|
||||
|
||||
DOCUMENT(R"(Show a new :class:`ShaderViewer` window, showing a read-only view of a debug trace
|
||||
through the execution of a given shader.
|
||||
|
||||
@@ -747,11 +747,11 @@ struct CaptureContextInvoker : ObjectForwarder<ICaptureContext>
|
||||
const rdcstrpairs &files, ShaderEncoding shaderEncoding,
|
||||
ShaderCompileFlags flags,
|
||||
IShaderViewer::SaveCallback saveCallback,
|
||||
IShaderViewer::CloseCallback closeCallback) override
|
||||
IShaderViewer::RevertCallback revertCallback) override
|
||||
{
|
||||
return InvokeRetFunction<IShaderViewer *>(&ICaptureContext::EditShader, id, stage, entryPoint,
|
||||
files, shaderEncoding, flags, saveCallback,
|
||||
closeCallback);
|
||||
revertCallback);
|
||||
}
|
||||
|
||||
virtual IShaderViewer *DebugShader(const ShaderBindpointMapping *bind,
|
||||
|
||||
@@ -322,6 +322,7 @@ void ShaderViewer::editShader(ResourceId id, ShaderStage stage, const QString &e
|
||||
|
||||
QWidget *w = (QWidget *)scintilla;
|
||||
w->setProperty("filename", kv.first);
|
||||
w->setProperty("origText", kv.second);
|
||||
|
||||
if(text.contains(entryPoint))
|
||||
sel = scintilla;
|
||||
@@ -526,6 +527,9 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR
|
||||
|
||||
// hide edit buttons
|
||||
ui->refresh->hide();
|
||||
ui->unrefresh->hide();
|
||||
ui->resetEdits->hide();
|
||||
ui->editStatusLabel->hide();
|
||||
ui->snippets->hide();
|
||||
ui->editSep->hide();
|
||||
|
||||
@@ -1130,7 +1134,7 @@ void ShaderViewer::gotoDisassemblyDebugging()
|
||||
|
||||
ShaderViewer *ShaderViewer::LoadEditor(ICaptureContext &ctx, QVariantMap data,
|
||||
IShaderViewer::SaveCallback saveCallback,
|
||||
IShaderViewer::CloseCallback closeCallback,
|
||||
IShaderViewer::RevertCallback revertCallback,
|
||||
ModifyCallback modifyCallback, QWidget *parent)
|
||||
{
|
||||
if(data.isEmpty())
|
||||
@@ -1181,7 +1185,7 @@ ShaderViewer *ShaderViewer::LoadEditor(ICaptureContext &ctx, QVariantMap data,
|
||||
}
|
||||
|
||||
ShaderViewer *view = EditShader(ctx, id, stage, entryPoint, files, encoding, flags, saveCallback,
|
||||
closeCallback, modifyCallback, parent);
|
||||
revertCallback, modifyCallback, parent);
|
||||
|
||||
int toolIndex = -1;
|
||||
|
||||
@@ -1266,8 +1270,8 @@ ShaderViewer::~ShaderViewer()
|
||||
|
||||
m_Ctx.Replay().AsyncInvoke([trace](IReplayController *r) { r->FreeTrace(trace); });
|
||||
|
||||
if(m_CloseCallback)
|
||||
m_CloseCallback(&m_Ctx, this, m_EditingShader);
|
||||
if(m_RevertCallback)
|
||||
m_RevertCallback(&m_Ctx, this, m_EditingShader);
|
||||
|
||||
if(m_ModifyCallback)
|
||||
m_ModifyCallback(this, true);
|
||||
@@ -2645,12 +2649,35 @@ bool ShaderViewer::getVar(RDTreeWidgetItem *item, ShaderVariable *var, QString *
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderViewer::setEditorWindowTitle()
|
||||
void ShaderViewer::updateEditState()
|
||||
{
|
||||
if(m_EditingShader != ResourceId())
|
||||
{
|
||||
if(!m_Ctx.IsResourceReplaced(m_EditingShader))
|
||||
m_Modified = true;
|
||||
QString statusString, statusTooltip;
|
||||
|
||||
// check if the shader is replaced and update the status
|
||||
if(m_Ctx.IsResourceReplaced(m_EditingShader))
|
||||
{
|
||||
statusString = tr("Status: Edited Shader Active");
|
||||
statusTooltip = tr("The replay currently has the original shader active");
|
||||
}
|
||||
else
|
||||
{
|
||||
statusString = tr("Status: Original Shader Active");
|
||||
statusTooltip = tr("The replay currently has an edited version of the shader active");
|
||||
|
||||
// if we expected it to be saved something went wrong
|
||||
if(m_Saved)
|
||||
{
|
||||
// we're still 'modified' as in have unsaved changes
|
||||
m_Modified = true;
|
||||
|
||||
statusTooltip.append(tr("\n\nSomething went wrong applying changes."));
|
||||
}
|
||||
}
|
||||
|
||||
ui->editStatusLabel->setText(statusString);
|
||||
ui->editStatusLabel->setToolTip(statusTooltip);
|
||||
|
||||
if(m_Modified)
|
||||
{
|
||||
@@ -4257,7 +4284,7 @@ void ShaderViewer::ShowErrors(const rdcstr &errors)
|
||||
ToolWindowManager::raiseToolWindow(m_Errors);
|
||||
}
|
||||
|
||||
setEditorWindowTitle();
|
||||
updateEditState();
|
||||
}
|
||||
|
||||
void ShaderViewer::AddWatch(const rdcstr &variable)
|
||||
@@ -4760,7 +4787,7 @@ void ShaderViewer::MarkModification()
|
||||
|
||||
m_Modified = true;
|
||||
|
||||
setEditorWindowTitle();
|
||||
updateEditState();
|
||||
}
|
||||
|
||||
void ShaderViewer::disasm_tooltipShow(int x, int y)
|
||||
@@ -5095,6 +5122,41 @@ bool ShaderViewer::ProcessIncludeDirectives(QString &source, const rdcstrpairs &
|
||||
return true;
|
||||
}
|
||||
|
||||
void ShaderViewer::on_resetEdits_clicked()
|
||||
{
|
||||
QMessageBox::StandardButton res = RDDialog::question(
|
||||
this, tr("Are you sure?"), tr("Are you sure you want to reset all edits and restore the "
|
||||
"shader source back to the original?"),
|
||||
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
|
||||
|
||||
if(res != QMessageBox::Yes)
|
||||
return;
|
||||
|
||||
for(ScintillaEdit *s : m_Scintillas)
|
||||
{
|
||||
QWidget *w = (QWidget *)s;
|
||||
s->selectAll();
|
||||
s->replaceSel(w->property("origText").toString().toUtf8().data());
|
||||
}
|
||||
|
||||
m_RevertCallback(&m_Ctx, this, m_EditingShader);
|
||||
|
||||
m_Modified = false;
|
||||
m_Saved = false;
|
||||
|
||||
updateEditState();
|
||||
}
|
||||
|
||||
void ShaderViewer::on_unrefresh_clicked()
|
||||
{
|
||||
m_RevertCallback(&m_Ctx, this, m_EditingShader);
|
||||
|
||||
m_Modified = true;
|
||||
m_Saved = false;
|
||||
|
||||
updateEditState();
|
||||
}
|
||||
|
||||
void ShaderViewer::on_refresh_clicked()
|
||||
{
|
||||
if(m_Trace)
|
||||
@@ -5134,6 +5196,8 @@ void ShaderViewer::on_refresh_clicked()
|
||||
return;
|
||||
}
|
||||
|
||||
m_Saved = true;
|
||||
|
||||
bytebuf shaderBytes(source.toUtf8());
|
||||
|
||||
rdcarray<ShaderEncoding> accepted = m_Ctx.TargetShaderEncodings();
|
||||
|
||||
@@ -78,7 +78,7 @@ public:
|
||||
|
||||
static ShaderViewer *LoadEditor(ICaptureContext &ctx, QVariantMap data,
|
||||
IShaderViewer::SaveCallback saveCallback,
|
||||
IShaderViewer::CloseCallback closeCallback,
|
||||
IShaderViewer::RevertCallback revertCallback,
|
||||
ModifyCallback modifyCallback, QWidget *parent);
|
||||
QVariantMap SaveEditor();
|
||||
|
||||
@@ -86,12 +86,12 @@ public:
|
||||
const QString &entryPoint, const rdcstrpairs &files,
|
||||
ShaderEncoding shaderEncoding, ShaderCompileFlags flags,
|
||||
IShaderViewer::SaveCallback saveCallback,
|
||||
IShaderViewer::CloseCallback closeCallback,
|
||||
IShaderViewer::RevertCallback revertCallback,
|
||||
ModifyCallback modifyCallback, QWidget *parent)
|
||||
{
|
||||
ShaderViewer *ret = new ShaderViewer(ctx, parent);
|
||||
ret->m_SaveCallback = saveCallback;
|
||||
ret->m_CloseCallback = closeCallback;
|
||||
ret->m_RevertCallback = revertCallback;
|
||||
ret->m_ModifyCallback = modifyCallback;
|
||||
ret->editShader(id, stage, entryPoint, files, shaderEncoding, flags);
|
||||
return ret;
|
||||
@@ -140,6 +140,8 @@ private slots:
|
||||
// automatic slots
|
||||
void on_findReplace_clicked();
|
||||
void on_refresh_clicked();
|
||||
void on_unrefresh_clicked();
|
||||
void on_resetEdits_clicked();
|
||||
void on_intView_clicked();
|
||||
void on_floatView_clicked();
|
||||
void on_debugToggle_clicked();
|
||||
@@ -261,10 +263,11 @@ private:
|
||||
} m_FindState;
|
||||
|
||||
SaveCallback m_SaveCallback;
|
||||
CloseCallback m_CloseCallback;
|
||||
RevertCallback m_RevertCallback;
|
||||
ModifyCallback m_ModifyCallback;
|
||||
|
||||
bool m_Modified = true;
|
||||
bool m_Saved = false;
|
||||
|
||||
ShaderDebugTrace *m_Trace = NULL;
|
||||
rdcarray<ShaderDebugState> m_States;
|
||||
@@ -338,7 +341,7 @@ private:
|
||||
|
||||
void find(bool down);
|
||||
|
||||
void setEditorWindowTitle();
|
||||
void updateEditState();
|
||||
|
||||
enum StepMode
|
||||
{
|
||||
|
||||
@@ -327,12 +327,32 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="refresh">
|
||||
<widget class="QToolButton" name="resetEdits">
|
||||
<property name="toolTip">
|
||||
<string>Compile Shader & Refresh changes</string>
|
||||
<string>Remove all source edits and restore original shader</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Refresh</string>
|
||||
<string>Reset</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../Resources/resources.qrc">
|
||||
<normaloff>:/del.png</normaloff>:/del.png</iconset>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextBesideIcon</enum>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="refresh">
|
||||
<property name="toolTip">
|
||||
<string>Compile shader & apply changes</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Apply changes</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../Resources/resources.qrc">
|
||||
@@ -346,6 +366,36 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="unrefresh">
|
||||
<property name="toolTip">
|
||||
<string>Use original shader</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remove changes</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../Resources/resources.qrc">
|
||||
<normaloff>:/arrow_undo.png</normaloff>:/arrow_undo.png</iconset>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextBesideIcon</enum>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="editStatusLabel">
|
||||
<property name="text">
|
||||
<string>Status: Original Shader Active</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>The replay currently has the original shader active</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="snippets">
|
||||
<property name="toolTip">
|
||||
|
||||
Reference in New Issue
Block a user