From 124d0e71b66e46db37d3f42e41394cac43644079 Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 21 Jul 2021 13:39:26 +0100 Subject: [PATCH] Implement more flexible step/run options. Closes #2276 Closes #2312 * We split stepping for source debugging into step over/into/out depending on how it handles function calls. Step Into is the same behaviour as before - it steps to the next source line executed regardless of if it's inside a function call. Step Over is similar but will not enter function calls. We define that as the callstack growing (so staying the same or shrinking - returning from a function - is OK), and this is as accurate as the underlying debug information. Step Out will run until the callstack shrinks, i.e. returning from a function. * This is a slight behaviour change of keyboard shortcuts - F10 was effectively doing step into and will now step over. F11 will step into which is the old behaviour. * All these variants have backwards versions, and to remain consistent we keep the shift modifier as forwards/backwards. This differs from visal studio where step out is shift-F10. * The seems like the best balance - using any other variant would likely confuse muscle memory of anyone used to visual studio (where these shortcuts are intended to mimick), if only because F10 would be step into whether or not F11 is used for step over or some other key which would likely be even more confusing either way. Trying to twist to use Shift-F10 for step out would be inconsistent with the other backwards running operations and likely cause more confusion than it saves in matching VS's shortcuts exactly. Also an accidental Shift-F10 is not too destructive, the user can realise it didn't Step Out forwards, and press Ctrl-F10 or look up the button. * The hope is that most likely people doing source debugging and familiar with these keys expect F10 to step over, so the previous behaviour was unexpected but easy to work around, and that changing the meaning of the key won't disrupt them. Or at least the disruption is less than other alternatives. --- qrenderdoc/Code/Resources.h | 150 +++---- .../Resources/control_reverse_base_blue.png | Bin 0 -> 670 bytes .../control_reverse_base_blue@2x.png | Bin 0 -> 2036 bytes .../Resources/control_reverse_cursor_blue.png | Bin 0 -> 710 bytes .../control_reverse_cursor_blue@2x.png | Bin 0 -> 2240 bytes .../Resources/control_reverse_nan_blue.png | Bin 0 -> 647 bytes .../Resources/control_reverse_nan_blue@2x.png | Bin 0 -> 2253 bytes .../Resources/control_reverse_sample_blue.png | Bin 0 -> 659 bytes .../control_reverse_sample_blue@2x.png | Bin 0 -> 2067 bytes qrenderdoc/Resources/resources.qrc | 8 + qrenderdoc/Windows/ShaderViewer.cpp | 383 ++++++++++++------ qrenderdoc/Windows/ShaderViewer.h | 22 +- qrenderdoc/Windows/ShaderViewer.ui | 375 ++++++----------- qrenderdoc/qrenderdoc_local.vcxproj | 10 + qrenderdoc/qrenderdoc_local.vcxproj.filters | 30 ++ 15 files changed, 526 insertions(+), 452 deletions(-) create mode 100644 qrenderdoc/Resources/control_reverse_base_blue.png create mode 100644 qrenderdoc/Resources/control_reverse_base_blue@2x.png create mode 100644 qrenderdoc/Resources/control_reverse_cursor_blue.png create mode 100644 qrenderdoc/Resources/control_reverse_cursor_blue@2x.png create mode 100644 qrenderdoc/Resources/control_reverse_nan_blue.png create mode 100644 qrenderdoc/Resources/control_reverse_nan_blue@2x.png create mode 100644 qrenderdoc/Resources/control_reverse_sample_blue.png create mode 100644 qrenderdoc/Resources/control_reverse_sample_blue@2x.png diff --git a/qrenderdoc/Code/Resources.h b/qrenderdoc/Code/Resources.h index 6ab088d38..6e69bc050 100644 --- a/qrenderdoc/Code/Resources.h +++ b/qrenderdoc/Code/Resources.h @@ -28,79 +28,83 @@ #include #include -#define RESOURCE_LIST() \ - RESOURCE_DEF(add, "add.png") \ - RESOURCE_DEF(arrow_in, "arrow_in.png") \ - RESOURCE_DEF(arrow_join, "arrow_join.png") \ - RESOURCE_DEF(arrow_left, "arrow_left.png") \ - RESOURCE_DEF(arrow_refresh, "arrow_refresh.png") \ - RESOURCE_DEF(arrow_right, "arrow_right.png") \ - RESOURCE_DEF(arrow_undo, "arrow_undo.png") \ - RESOURCE_DEF(asterisk_orange, "asterisk_orange.png") \ - RESOURCE_DEF(bug, "bug.png") \ - RESOURCE_DEF(chart_curve, "chart_curve.png") \ - RESOURCE_DEF(cog, "cog.png") \ - RESOURCE_DEF(color_wheel, "color_wheel.png") \ - RESOURCE_DEF(copy, "copy.png") \ - RESOURCE_DEF(connect, "connect.png") \ - RESOURCE_DEF(control_base_blue, "control_base_blue.png") \ - RESOURCE_DEF(control_cursor_blue, "control_cursor_blue.png") \ - RESOURCE_DEF(control_end_blue, "control_end_blue.png") \ - RESOURCE_DEF(control_play_blue, "control_play_blue.png") \ - RESOURCE_DEF(control_nan_blue, "control_nan_blue.png") \ - RESOURCE_DEF(control_reverse_blue, "control_reverse_blue.png") \ - RESOURCE_DEF(control_sample_blue, "control_sample_blue.png") \ - RESOURCE_DEF(control_start_blue, "control_start_blue.png") \ - RESOURCE_DEF(cross, "cross.png") \ - RESOURCE_DEF(checkerboard, "checkerboard.png") \ - RESOURCE_DEF(cut, "cut.png") \ - RESOURCE_DEF(del, "del.png") \ - RESOURCE_DEF(disconnect, "disconnect.png") \ - RESOURCE_DEF(find, "find.png") \ - RESOURCE_DEF(filter, "filter.png") \ - RESOURCE_DEF(filter_reapply, "filter_reapply.png") \ - RESOURCE_DEF(arrow_out, "arrow_out.png") \ - RESOURCE_DEF(flag_green, "flag_green.png") \ - RESOURCE_DEF(flip_y, "flip_y.png") \ - RESOURCE_DEF(folder, "folder.png") \ - RESOURCE_DEF(folder_page_white, "folder_page_white.png") \ - RESOURCE_DEF(hourglass, "hourglass.png") \ - RESOURCE_DEF(house, "house.png") \ - RESOURCE_DEF(information, "information.png") \ - RESOURCE_DEF(link, "link.png") \ - RESOURCE_DEF(page_go, "page_go.png") \ - RESOURCE_DEF(page_white_code, "page_white_code.png") \ - RESOURCE_DEF(page_white_database, "page_white_database.png") \ - RESOURCE_DEF(page_white_delete, "page_white_delete.png") \ - RESOURCE_DEF(page_white_edit, "page_white_edit.png") \ - RESOURCE_DEF(page_white_link, "page_white_link.png") \ - RESOURCE_DEF(page_white_stack, "page_white_stack.png") \ - RESOURCE_DEF(paste, "paste.png") \ - RESOURCE_DEF(pixel_history, "pixel_history.png") \ - RESOURCE_DEF(plugin, "plugin.png") \ - RESOURCE_DEF(plugin_add, "plugin_add.png") \ - RESOURCE_DEF(save, "save.png") \ - RESOURCE_DEF(text_add, "text_add.png") \ - RESOURCE_DEF(tick, "tick.png") \ - RESOURCE_DEF(time, "time.png") \ - RESOURCE_DEF(timeline_marker, "timeline_marker.png") \ - RESOURCE_DEF(upfolder, "upfolder.png") \ - RESOURCE_DEF(update, "update.png") \ - RESOURCE_DEF(wand, "wand.png") \ - RESOURCE_DEF(wireframe_mesh, "wireframe_mesh.png") \ - RESOURCE_DEF(wrench, "wrench.png") \ - RESOURCE_DEF(zoom, "zoom.png") \ - RESOURCE_DEF(topo_linelist, "topologies/topo_linelist.svg") \ - RESOURCE_DEF(topo_linelist_adj, "topologies/topo_linelist_adj.svg") \ - RESOURCE_DEF(topo_linestrip, "topologies/topo_linestrip.svg") \ - RESOURCE_DEF(topo_linestrip_adj, "topologies/topo_linestrip_adj.svg") \ - RESOURCE_DEF(topo_patch, "topologies/topo_patch.svg") \ - RESOURCE_DEF(topo_pointlist, "topologies/topo_pointlist.svg") \ - RESOURCE_DEF(topo_trilist, "topologies/topo_trilist.svg") \ - RESOURCE_DEF(topo_trilist_adj, "topologies/topo_trilist_adj.svg") \ - RESOURCE_DEF(topo_tristrip, "topologies/topo_tristrip.svg") \ - RESOURCE_DEF(topo_tristrip_adj, "topologies/topo_tristrip_adj.svg") \ - RESOURCE_DEF(action, "action.png") \ +#define RESOURCE_LIST() \ + RESOURCE_DEF(add, "add.png") \ + RESOURCE_DEF(arrow_in, "arrow_in.png") \ + RESOURCE_DEF(arrow_join, "arrow_join.png") \ + RESOURCE_DEF(arrow_left, "arrow_left.png") \ + RESOURCE_DEF(arrow_refresh, "arrow_refresh.png") \ + RESOURCE_DEF(arrow_right, "arrow_right.png") \ + RESOURCE_DEF(arrow_undo, "arrow_undo.png") \ + RESOURCE_DEF(asterisk_orange, "asterisk_orange.png") \ + RESOURCE_DEF(bug, "bug.png") \ + RESOURCE_DEF(chart_curve, "chart_curve.png") \ + RESOURCE_DEF(cog, "cog.png") \ + RESOURCE_DEF(color_wheel, "color_wheel.png") \ + RESOURCE_DEF(copy, "copy.png") \ + RESOURCE_DEF(connect, "connect.png") \ + RESOURCE_DEF(control_base_blue, "control_base_blue.png") \ + RESOURCE_DEF(control_cursor_blue, "control_cursor_blue.png") \ + RESOURCE_DEF(control_end_blue, "control_end_blue.png") \ + RESOURCE_DEF(control_play_blue, "control_play_blue.png") \ + RESOURCE_DEF(control_nan_blue, "control_nan_blue.png") \ + RESOURCE_DEF(control_reverse_blue, "control_reverse_blue.png") \ + RESOURCE_DEF(control_reverse_base_blue, "control_reverse_base_blue.png") \ + RESOURCE_DEF(control_reverse_cursor_blue, "control_reverse_cursor_blue.png") \ + RESOURCE_DEF(control_reverse_nan_blue, "control_reverse_nan_blue.png") \ + RESOURCE_DEF(control_reverse_sample_blue, "control_reverse_sample_blue.png") \ + RESOURCE_DEF(control_sample_blue, "control_sample_blue.png") \ + RESOURCE_DEF(control_start_blue, "control_start_blue.png") \ + RESOURCE_DEF(cross, "cross.png") \ + RESOURCE_DEF(checkerboard, "checkerboard.png") \ + RESOURCE_DEF(cut, "cut.png") \ + RESOURCE_DEF(del, "del.png") \ + RESOURCE_DEF(disconnect, "disconnect.png") \ + RESOURCE_DEF(find, "find.png") \ + RESOURCE_DEF(filter, "filter.png") \ + RESOURCE_DEF(filter_reapply, "filter_reapply.png") \ + RESOURCE_DEF(arrow_out, "arrow_out.png") \ + RESOURCE_DEF(flag_green, "flag_green.png") \ + RESOURCE_DEF(flip_y, "flip_y.png") \ + RESOURCE_DEF(folder, "folder.png") \ + RESOURCE_DEF(folder_page_white, "folder_page_white.png") \ + RESOURCE_DEF(hourglass, "hourglass.png") \ + RESOURCE_DEF(house, "house.png") \ + RESOURCE_DEF(information, "information.png") \ + RESOURCE_DEF(link, "link.png") \ + RESOURCE_DEF(page_go, "page_go.png") \ + RESOURCE_DEF(page_white_code, "page_white_code.png") \ + RESOURCE_DEF(page_white_database, "page_white_database.png") \ + RESOURCE_DEF(page_white_delete, "page_white_delete.png") \ + RESOURCE_DEF(page_white_edit, "page_white_edit.png") \ + RESOURCE_DEF(page_white_link, "page_white_link.png") \ + RESOURCE_DEF(page_white_stack, "page_white_stack.png") \ + RESOURCE_DEF(paste, "paste.png") \ + RESOURCE_DEF(pixel_history, "pixel_history.png") \ + RESOURCE_DEF(plugin, "plugin.png") \ + RESOURCE_DEF(plugin_add, "plugin_add.png") \ + RESOURCE_DEF(save, "save.png") \ + RESOURCE_DEF(text_add, "text_add.png") \ + RESOURCE_DEF(tick, "tick.png") \ + RESOURCE_DEF(time, "time.png") \ + RESOURCE_DEF(timeline_marker, "timeline_marker.png") \ + RESOURCE_DEF(upfolder, "upfolder.png") \ + RESOURCE_DEF(update, "update.png") \ + RESOURCE_DEF(wand, "wand.png") \ + RESOURCE_DEF(wireframe_mesh, "wireframe_mesh.png") \ + RESOURCE_DEF(wrench, "wrench.png") \ + RESOURCE_DEF(zoom, "zoom.png") \ + RESOURCE_DEF(topo_linelist, "topologies/topo_linelist.svg") \ + RESOURCE_DEF(topo_linelist_adj, "topologies/topo_linelist_adj.svg") \ + RESOURCE_DEF(topo_linestrip, "topologies/topo_linestrip.svg") \ + RESOURCE_DEF(topo_linestrip_adj, "topologies/topo_linestrip_adj.svg") \ + RESOURCE_DEF(topo_patch, "topologies/topo_patch.svg") \ + RESOURCE_DEF(topo_pointlist, "topologies/topo_pointlist.svg") \ + RESOURCE_DEF(topo_trilist, "topologies/topo_trilist.svg") \ + RESOURCE_DEF(topo_trilist_adj, "topologies/topo_trilist_adj.svg") \ + RESOURCE_DEF(topo_tristrip, "topologies/topo_tristrip.svg") \ + RESOURCE_DEF(topo_tristrip_adj, "topologies/topo_tristrip_adj.svg") \ + RESOURCE_DEF(action, "action.png") \ RESOURCE_DEF(action_hover, "action_hover.png") struct Resource diff --git a/qrenderdoc/Resources/control_reverse_base_blue.png b/qrenderdoc/Resources/control_reverse_base_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..e11a21cf9144a3cdf48ad2b85dbedd4d88971e63 GIT binary patch literal 670 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 O0000Px#32;bRa{vGi!TZHy#Hf{1Mw zR;<{JFhvapLPASQYMM?=GD+rm&&$j-P5R()-o10rdGFnMudAzV9J>1c-oRwE+&>&;faxFG0u$4^iI)P#taUl_w+7aG20YtS+4iOd%oruS5%gRPVfe|i ziV4=v8m8hI;VG%7P8keNMk+ZuWB6wY^VtRhqi->{l0o2dSmh{c$GT~QI%U8vb9~9! zI4I(~ACl1SETI3&J4BOZ1&X4{e;#u52k{tz2t07@UYyGxFaTvlf0!FM4Gsx4)L) z7qi7|bHj^Da{F@U8Kq*JIE(D$qCUyO78e4UdQ9CU&11JKO#i z_A{wTV~nkaz=lx}F4$NVUKPGC$K=Y6cwfh3a*~0*k>G1KNON8ynKASH?uz#^aEDLe hcZyy3oqWf0{tx45R5n(a>zn`p002ovPDHLkV1i(#BcA{O literal 0 HcmV?d00001 diff --git a/qrenderdoc/Resources/control_reverse_nan_blue@2x.png b/qrenderdoc/Resources/control_reverse_nan_blue@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7ae7b4bc72aae1abb1267e48580c5d3c4c90dbe2 GIT binary patch literal 2253 zcmV;;2r~DHP)Px#32;bRa{vGi!TTX0kKioO91T_nzWBc{A8b2fOWQUAN#QHjBn^SGh)Z-r=ybd z8rP&=MtXh|ZkTPD^aU{e$2RUu(=~y8c?^%`IlgZ2S<%TCj>o26LT*jB2;w8O4*787 z)+BTm*F9hx_xWT(nyPN_Se}FDdf4EPMDEx1?#M7;!V|!_7tnXPaHeh?8TI2hOZape z*v5VAqwjKyF{5rjwx6j)6wSqRK5%eFa-Q`}aXWaUTkJk$8YghBVFI5wP6%Bo<1@B3 zj0uM z)|(_-P|q?=+>y-=D9O%qxroFcPgfu+QFZcv<;2Y838_og9=r^j!;fa#x@?mJ=NZit z1X)sB*ER`ln;V)ICsfqF53;|C2&l~tZ4+ZM8|4fWDJ_@eJ)#g5gy`w<^ zk;#?&*e|I6cK7?38}hhV1h>=9>p>y#PptuERu2Z80jz%aA~@#M*{|A}vG3poBL>_+ zUaOPflBC5cw}=9$b0QPfri(@!%tL#(7tJ;&BKPOBZwM0zRU~UMOy^%hXLN;<>nfrA zb^y!Y&OuJ24eLKPV8gL0{OqU!rz<4_W&HtM=^)<@7dG!sr2q+dK0HzoV4d;O%kiQe z9U<~@opL|gK$pdA?WehGmJ%7G%PT18zR)Y&19;1i0pNqG|q z1eQni{enO(^%v2E!e79Rr+)k_Ht$N2>^+lM7yoOlj9w%38{HluEBk$Dp{o#aHvw*R zjstarev}ajJ=Fq6!w{2DA+6Mo&FU_^k#h@&^)^AEp8E9GN#VC5B1UZWS0TH+1r7E9 zYOD@=7xJeFghuQ+Zz-^hz&sidXT(Rr`M|Pi6j(td4(RRpgSHQ;`XPi0|KUfmB@yK=9C^;I3eK3$xJ?KN_Z7-dfS4gVNf<$te zTNEY}9hvASR1nr|d=)=^Ic~~-$AKgGE+ruA2H93g^R|up5S@~bM=55o5OFzNq}Y?) z_PL=KU9<}|lnb?lDw~hsMb&MR12mZWp4+Ly_OsPu2dc?dZIkfiQ%_@i%3)~?+1GA- z4bkg1$o)Qn9$Nh&t%hBS`&oW$LD>3@akL8^6M%)bypEpF8rp^0fgrr1-9mk4 z3f@R%o9#8+NA?q%0$efn2%YVjg;h|MHc4$^^TSMKIEq%kkYaJnd!A#$;_yEm*X+%1 z0PPseV*xbKaqyAU6PY@@pQK;tccfS7OtyZ=JIx;Slh8oe^si#Pxa|`S$GYb^mOl>W z5|$|v)q|PUeW2t<3!Sr(SThM;v5?#z^55T{*2m+FBYw2f9JKrRtEPz_Ak84hkYnBV zxjsw2mx@(;at4$&y`ZBZ;n0bd;_S=qsJ`~;ni5i1C$36IEZhV>(laD8o(_2JBz=600000NkvXXu0mjfy9z?; literal 0 HcmV?d00001 diff --git a/qrenderdoc/Resources/control_reverse_sample_blue.png b/qrenderdoc/Resources/control_reverse_sample_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..bcd4d4bbd6d8a46c37c6697aa0dcf4d92178a28c GIT binary patch literal 659 zcmV;E0&M+>P)Px#32;bRa{vGi!T) zcdrG|Dh^zU4*16+2+SstGtm~C1>nhCl1AXV{|uyg;^4I?jBFWC<69QAd@J99!`EX? zlcoW8PGu|jl>;V!Yza(EY9?L?SU+bi%-Z-{1=lwXc(=!L?2QUAr5Es8(0MM1!AFa# zzU9Mrs4@%Pn|O89}kx@a>vk00ki2ke8V%CUNYdj5K=t~W^4|vY%5+f8=y`Z zaLSA?nFjWW`1bn*{I}-Nd+{wIiJ}5Uk%T2CGi;q@(2%V2>@=F^tI;ZKIesl3cUbk+&Z1YX{ksV=Nl@YzPk&>Nh7_FZ~a1&S6{9j@Ts z$3LJ>8Ay2fUl-S__?8hUuBqJVQOKOkZ++G~@Hz&buE86lhptAUt(Tx})Y=fw67?nz z$V==vK60w&*>4LP`~&CGXp%_%iueEk002ovPDHLkV1hBgCYS&K literal 0 HcmV?d00001 diff --git a/qrenderdoc/Resources/control_reverse_sample_blue@2x.png b/qrenderdoc/Resources/control_reverse_sample_blue@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd46f6d16df6538f1ce9311cfc1e301a2932716 GIT binary patch literal 2067 zcmV+u2<-QXP)Px#32;bRa{vGi!T72nCRD2Oj@l9L*#-S9d6HfFqb z@taw>9!#rR=PH;?78vY>x4;` zVY3L>l5x_Cv0xm{-iRu^$xSA0{%2cod__a zbsDO+dNf2EQoc@D&5NmeBq`t{6(?$&I0Ms>PZ7|>Jy63_t7asOPCwKVyho-3#(OwO zh<(R4p#*d=U&8^VUMEt0$CAW%B~Hzc@!=+-=;N!9kt#rf;YFZxI)(;{u<+UM|99;8pwMMcOvLD3u&I7wC;Q~|Pyldq$~$>|wsRIbrgTJ9+{c`Y5tLIl%KQ_<%`&^naH|! zy)J=n;=n&@@$9ePGYi+6>sb3Zc$C;_IBuH0*5(B_Ec&?4cB&Q;^2EwYJQMqPye=pG z>~k^na}2HuesAvO1!SHU4vp($pX-~n_tLQEXvvhZeH>hR407}Jav;ZSoHnlfWSp?; zeFuGcrH8m@ruiv$%G?9qxKlE=#__42>GHw2oyasCEAgMW-VGk};Nhl($kVtNtgEE$+b!f4GSZ_L08Yns0j;^3**co8=qCvtRnkllz}KkXNwh zb>m=$`g3Yo18Fn7VH|wwU|xaLN*}H7qo3ukS?b&Ii1yCP!LdV|&V9s->#$GD?a*o; x*ZOY!y#6U~(vHq8+9k4W9kyz@%@6a${{^~$D+->%o?rj~002ovPDHLkV1i}D1dRXy literal 0 HcmV?d00001 diff --git a/qrenderdoc/Resources/resources.qrc b/qrenderdoc/Resources/resources.qrc index 4522456e1..05048cef5 100644 --- a/qrenderdoc/Resources/resources.qrc +++ b/qrenderdoc/Resources/resources.qrc @@ -59,6 +59,14 @@ control_play_blue@2x.png control_reverse_blue.png control_reverse_blue@2x.png + control_reverse_base_blue.png + control_reverse_base_blue@2x.png + control_reverse_cursor_blue.png + control_reverse_cursor_blue@2x.png + control_reverse_nan_blue.png + control_reverse_nan_blue@2x.png + control_reverse_sample_blue.png + control_reverse_sample_blue@2x.png control_sample_blue.png control_sample_blue@2x.png control_start_blue.png diff --git a/qrenderdoc/Windows/ShaderViewer.cpp b/qrenderdoc/Windows/ShaderViewer.cpp index bc7b0d859..6f7a6d7e2 100644 --- a/qrenderdoc/Windows/ShaderViewer.cpp +++ b/qrenderdoc/Windows/ShaderViewer.cpp @@ -32,6 +32,7 @@ #include #include #include +#include "Code/Resources.h" #include "Code/ScintillaSyntax.h" #include "Widgets/FindReplace.h" #include "scintilla/include/SciLexer.h" @@ -280,14 +281,9 @@ void ShaderViewer::editShader(ResourceId id, ShaderStage stage, const QString &e ui->snippets->setVisible(m_CustomShader); // hide debugging toolbar buttons - ui->debugSep->hide(); - ui->runBack->hide(); - ui->run->hide(); - ui->stepBack->hide(); - ui->stepNext->hide(); - ui->runToCursor->hide(); - ui->runToSample->hide(); - ui->runToNaNOrInf->hide(); + ui->editSep->hide(); + ui->execBackwards->hide(); + ui->execForwards->hide(); ui->regFormatSep->hide(); ui->intView->hide(); ui->floatView->hide(); @@ -529,9 +525,9 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR } // hide edit buttons - ui->editSep->hide(); ui->refresh->hide(); ui->snippets->hide(); + ui->editSep->hide(); if(m_Trace) { @@ -539,6 +535,13 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR ui->inputSig->hide(); ui->outputSig->hide(); + // hide int/float toggles except on DXBC, other encodings are strongly typed + if(m_ShaderDetails->encoding != ShaderEncoding::DXBC) + { + ui->intView->hide(); + ui->floatView->hide(); + } + if(m_ShaderDetails->debugInfo.files.isEmpty()) { ui->debugToggle->setEnabled(false); @@ -647,13 +650,144 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR if(!hasLineInfo) ui->docking->raiseToolWindow(ui->debugVars); - QObject::connect(ui->stepBack, &QToolButton::clicked, this, &ShaderViewer::stepBack); - QObject::connect(ui->stepNext, &QToolButton::clicked, this, &ShaderViewer::stepNext); - QObject::connect(ui->runBack, &QToolButton::clicked, this, &ShaderViewer::runBack); - QObject::connect(ui->run, &QToolButton::clicked, this, &ShaderViewer::run); - QObject::connect(ui->runToCursor, &QToolButton::clicked, this, &ShaderViewer::runToCursor); - QObject::connect(ui->runToSample, &QToolButton::clicked, this, &ShaderViewer::runToSample); - QObject::connect(ui->runToNaNOrInf, &QToolButton::clicked, this, &ShaderViewer::runToNanOrInf); + // set up stepping/running actions + + // we register the shortcuts via MainWindow so that it works regardless of the active scintilla + // but still handles multiple shader viewers being present (the one with focus will get the + // input) + + // all shortcuts have a reverse version with shift. This means step out is Ctrl-F11 instead of + // Shift-F11, but otherwise the shortcuts behave the same as visual studio + + { + QMenu *backwardsMenu = new QMenu(this); + QAction *act; + + act = MakeExecuteAction(tr("&Run backwards"), Icons::control_start_blue(), + tr("Run backwards to the start of the shader"), + QKeySequence(Qt::Key_F5 | Qt::ShiftModifier)); + + QObject::connect(act, &QAction::triggered, [this]() { runTo({}, false); }); + backwardsMenu->addAction(act); + + act = MakeExecuteAction( + tr("Run backwards to &Cursor"), Icons::control_reverse_cursor_blue(), + tr("Run backwards until execution reaches the cursor, or the start of the shader"), + QKeySequence(Qt::Key_F10 | Qt::ControlModifier | Qt::ShiftModifier)); + + QObject::connect(act, &QAction::triggered, [this]() { runToCursor(false); }); + backwardsMenu->addAction(act); + + act = MakeExecuteAction(tr("Run backwards to &Sample"), Icons::control_reverse_sample_blue(), + tr("Run backwards until execution reads from a resource, or the " + "start of the shader is reached"), + QKeySequence()); + + QObject::connect(act, &QAction::triggered, + [this]() { runTo({}, false, ShaderEvents::SampleLoadGather); }); + backwardsMenu->addAction(act); + + act = MakeExecuteAction( + tr("Run backwards to &NaN/Inf"), Icons::control_reverse_nan_blue(), + tr("Run backwards until a floating point instruction generates a NaN " + "or Inf, an integer instruction divides by 0, or the start of the shader is reached"), + QKeySequence()); + + QObject::connect(act, &QAction::triggered, + [this]() { runTo({}, false, ShaderEvents::GeneratedNanOrInf); }); + backwardsMenu->addAction(act); + + backwardsMenu->addSeparator(); + + act = MakeExecuteAction(tr("Step backwards &Over"), Icons::control_reverse_blue(), + tr("Step backwards, and don't enter functions when source debugging"), + QKeySequence(Qt::Key_F10 | Qt::ShiftModifier)); + + QObject::connect(act, &QAction::triggered, [this]() { step(false, StepOver); }); + backwardsMenu->addAction(act); + + act = MakeExecuteAction(tr("Step backwards &Into"), Icons::control_reverse_blue(), + tr("Step backwards, entering functions when source debugging"), + QKeySequence(Qt::Key_F11 | Qt::ShiftModifier)); + + QObject::connect(act, &QAction::triggered, [this]() { step(false, StepInto); }); + backwardsMenu->addAction(act); + + act = + MakeExecuteAction(tr("Step backwards Ou&t"), Icons::control_reverse_blue(), + tr("Step backwards, out of the current function when source debugging"), + QKeySequence(Qt::Key_F11 | Qt::ControlModifier | Qt::ShiftModifier)); + + QObject::connect(act, &QAction::triggered, [this]() { step(false, StepOut); }); + backwardsMenu->addAction(act); + + ui->execBackwards->setMenu(backwardsMenu); + } + + { + QMenu *forwardsMenu = new QMenu(this); + QAction *act; + + act = MakeExecuteAction(tr("&Run forwards"), Icons::control_end_blue(), + tr("Run forwards to the start of the shader"), + QKeySequence(Qt::Key_F5)); + + QObject::connect(act, &QAction::triggered, [this]() { runTo({}, true); }); + forwardsMenu->addAction(act); + + act = MakeExecuteAction( + tr("Run forwards to &Cursor"), Icons::control_cursor_blue(), + tr("Run forwards until execution reaches the cursor, or the end of the shader"), + QKeySequence(Qt::Key_F10 | Qt::ControlModifier)); + + QObject::connect(act, &QAction::triggered, [this]() { runToCursor(true); }); + forwardsMenu->addAction(act); + + act = MakeExecuteAction(tr("Run forwards to &Sample"), Icons::control_sample_blue(), + tr("Run forwards until execution reads from a resource, or the " + "end of the shader is reached"), + QKeySequence()); + + QObject::connect(act, &QAction::triggered, + [this]() { runTo({}, true, ShaderEvents::SampleLoadGather); }); + forwardsMenu->addAction(act); + + act = MakeExecuteAction( + tr("Run forwards to &NaN/Inf"), Icons::control_nan_blue(), + tr("Run forwards until a floating point instruction generates a NaN " + "or Inf, an integer instruction divides by 0, or the end of the shader is reached"), + QKeySequence()); + + QObject::connect(act, &QAction::triggered, + [this]() { runTo({}, true, ShaderEvents::GeneratedNanOrInf); }); + forwardsMenu->addAction(act); + + forwardsMenu->addSeparator(); + + act = MakeExecuteAction(tr("Step forwards &Over"), Icons::control_play_blue(), + tr("Step forwards, and don't enter functions when source debugging"), + QKeySequence(Qt::Key_F10)); + + QObject::connect(act, &QAction::triggered, [this]() { step(true, StepOver); }); + forwardsMenu->addAction(act); + + act = MakeExecuteAction(tr("Step forwards &Into"), Icons::control_play_blue(), + tr("Step forwards, entering functions when source debugging"), + QKeySequence(Qt::Key_F11)); + + QObject::connect(act, &QAction::triggered, [this]() { step(true, StepInto); }); + forwardsMenu->addAction(act); + + act = + MakeExecuteAction(tr("Step forwards Ou&t"), Icons::control_play_blue(), + tr("Step forwards, out of the current function when source debugging"), + QKeySequence(Qt::Key_F11 | Qt::ControlModifier)); + + QObject::connect(act, &QAction::triggered, [this]() { step(true, StepOut); }); + forwardsMenu->addAction(act); + + ui->execForwards->setMenu(forwardsMenu); + } for(ScintillaEdit *edit : m_Scintillas) { @@ -678,19 +812,7 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR QObject::connect(edit, &ScintillaEdit::dwellEnd, this, &ShaderViewer::disasm_tooltipHide); } - // register the shortcuts via MainWindow so that it works regardless of the active scintilla but - // still handles multiple shader viewers being present (the one with focus will get the input) - m_Ctx.GetMainWindow()->RegisterShortcut(QKeySequence(Qt::Key_F10).toString(), this, - [this](QWidget *) { stepNext(); }); - m_Ctx.GetMainWindow()->RegisterShortcut(QKeySequence(Qt::Key_F10 | Qt::ShiftModifier).toString(), - this, [this](QWidget *) { stepBack(); }); - m_Ctx.GetMainWindow()->RegisterShortcut( - QKeySequence(Qt::Key_F10 | Qt::ControlModifier).toString(), this, - [this](QWidget *) { runToCursor(); }); - m_Ctx.GetMainWindow()->RegisterShortcut(QKeySequence(Qt::Key_F5).toString(), this, - [this](QWidget *) { run(); }); - m_Ctx.GetMainWindow()->RegisterShortcut(QKeySequence(Qt::Key_F5 | Qt::ShiftModifier).toString(), - this, [this](QWidget *) { runBack(); }); + // toggle breakpoint - F9 m_Ctx.GetMainWindow()->RegisterShortcut(QKeySequence(Qt::Key_F9).toString(), this, [this](QWidget *) { ToggleBreakpointOnInstruction(); }); @@ -830,14 +952,9 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR ui->callstack->hide(); // hide debugging toolbar buttons - ui->debugSep->hide(); - ui->runBack->hide(); - ui->run->hide(); - ui->stepBack->hide(); - ui->stepNext->hide(); - ui->runToCursor->hide(); - ui->runToSample->hide(); - ui->runToNaNOrInf->hide(); + ui->editSep->hide(); + ui->execBackwards->hide(); + ui->execForwards->hide(); ui->regFormatSep->hide(); ui->intView->hide(); ui->floatView->hide(); @@ -958,6 +1075,24 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR } } +QAction *ShaderViewer::MakeExecuteAction(QString name, const QIcon &icon, QString tooltip, + QKeySequence shortcut) +{ + QAction *act = new QAction(name, this); + // set the shortcut context to something that shouldn't fire, since we want to handle this + // ourselves - we just want Qt to *display* the shortcut + act->setShortcutContext(Qt::WidgetShortcut); + act->setToolTip(tooltip); + act->setIcon(icon); + if(!shortcut.isEmpty()) + { + act->setShortcut(shortcut); + m_Ctx.GetMainWindow()->RegisterShortcut(act->shortcut().toString(), this, + [act](QWidget *) { act->activate(QAction::Trigger); }); + } + return act; +} + void ShaderViewer::updateWindowTitle() { if(m_ShaderDetails) @@ -1337,19 +1472,29 @@ void ShaderViewer::debug_contextMenu(const QPoint &pos) contextMenu.addSeparator(); QAction addBreakpoint(tr("Toggle breakpoint here"), this); - QAction runCursor(tr("Run to Cursor"), this); + QAction runForwardCursor(tr("Run forwards to Cursor"), this); + QAction runBackwardCursor(tr("Run backwards to Cursor"), this); + + addBreakpoint.setShortcut(QKeySequence(Qt::Key_F9)); + runForwardCursor.setShortcut(QKeySequence(Qt::Key_F10 | Qt::ControlModifier)); + runBackwardCursor.setShortcut(QKeySequence(Qt::Key_F10 | Qt::ControlModifier | Qt::ShiftModifier)); QObject::connect(&addBreakpoint, &QAction::triggered, [this, scintillaPos] { m_DisassemblyView->setSelection(scintillaPos, scintillaPos); ToggleBreakpointOnInstruction(); }); - QObject::connect(&runCursor, &QAction::triggered, [this, scintillaPos] { + QObject::connect(&runForwardCursor, &QAction::triggered, [this, scintillaPos] { m_DisassemblyView->setSelection(scintillaPos, scintillaPos); - runToCursor(); + runToCursor(true); + }); + QObject::connect(&runBackwardCursor, &QAction::triggered, [this, scintillaPos] { + m_DisassemblyView->setSelection(scintillaPos, scintillaPos); + runToCursor(false); }); contextMenu.addAction(&addBreakpoint); - contextMenu.addAction(&runCursor); + contextMenu.addAction(&runBackwardCursor); + contextMenu.addAction(&runForwardCursor); contextMenu.addSeparator(); QAction copyText(tr("Copy"), this); @@ -1682,100 +1827,120 @@ void ShaderViewer::on_watch_itemChanged(QTableWidgetItem *item) updateDebugState(); } -bool ShaderViewer::stepBack() +bool ShaderViewer::step(bool forward, StepMode mode) { if(!m_Trace || m_States.empty()) return false; - if(IsFirstState()) + if((forward && IsLastState()) || (!forward && IsFirstState())) return false; if(isSourceDebugging()) { LineColumnInfo oldLine = m_Trace->lineInfo[GetCurrentState().nextInstruction]; + rdcarray oldStack = GetCurrentState().callstack; - // first step to the next instruction in a backwards direction that's on a different line from - // the current one do { - applyBackwardsChange(); + // step once in the right direction + if(forward) + applyForwardsChange(); + else + applyBackwardsChange(); + // break out if we hit a breakpoint, no matter what if(m_Breakpoints.contains((int)GetCurrentState().nextInstruction)) break; - if(IsFirstState()) + // if we've reached the limit, break + if((forward && IsLastState()) || (!forward && IsFirstState())) break; - if(m_Trace->lineInfo[GetCurrentState().nextInstruction].SourceEqual(oldLine)) + // keep going if we're still on the same source line as we started + LineColumnInfo curLine = m_Trace->lineInfo[GetCurrentState().nextInstruction]; + if(curLine.SourceEqual(oldLine)) continue; - break; + // if we're stepping into, break now as soon as we hit a different line + if(mode == StepInto) + break; + + // we're on a different line but that might not be enough for Step Out or Step Over + rdcarray curStack = GetCurrentState().callstack; + + // mode is StepOver or StepOut + + if(mode == StepOver) + { + // if the stack hasn't grown, we assume that we're still in the same function so return + if(curStack.size() <= oldStack.size()) + break; + } + + if(mode == StepOut) + { + // if the stack has shrunk we must have exited the function + if(curStack.size() < oldStack.size()) + break; + } + + // if the stack is bigger (for stepover) or hasn't shrunk (for stepout) but the common subset + // is different, we have stepped into a different function due to inlining, so break + // + // E.g. A() -> B() stepover A() -> C() -> D() + // + // Or A() -> B() stepout A() -> C() + bool different = false; + for(size_t i = 0; i < qMin(curStack.size(), oldStack.size()); i++) + { + if(oldStack[i] != curStack[i]) + { + different = true; + break; + } + } + + if(different) + break; + } while(true); oldLine = m_Trace->lineInfo[GetCurrentState().nextInstruction]; - // now since a line can have multiple instructions, keep stepping (looking forward) until we - // reach the first instruction with an identical line info - while(!IsFirstState() && - m_Trace->lineInfo[GetPreviousState().nextInstruction].SourceEqual(oldLine)) + if(!forward) { - applyBackwardsChange(); + // now since a line can have multiple instructions, we may only be on the last one of several. + // Keep stepping until we reach the first instruction with an identical line info and stop + // there + while(!IsFirstState() && + m_Trace->lineInfo[GetPreviousState().nextInstruction].SourceEqual(oldLine)) + { + applyBackwardsChange(); - if(m_Breakpoints.contains((int)GetCurrentState().nextInstruction)) - break; + // still need to check for instruction-level breakpoints + if(m_Breakpoints.contains((int)GetCurrentState().nextInstruction)) + break; + } } updateDebugState(); } else { - applyBackwardsChange(); - updateDebugState(); - } + // non-source stepping is easy, we just do one instruction in that direction regardless of step + // mode - return true; -} - -bool ShaderViewer::stepNext() -{ - if(!m_Trace || m_States.empty()) - return false; - - if(IsLastState()) - return false; - - if(isSourceDebugging()) - { - LineColumnInfo oldLine = m_Trace->lineInfo[GetCurrentState().nextInstruction]; - - do - { + if(forward) applyForwardsChange(); - - if(m_Breakpoints.contains((int)GetCurrentState().nextInstruction)) - break; - - if(IsLastState()) - break; - - if(m_Trace->lineInfo[GetCurrentState().nextInstruction].SourceEqual(oldLine)) - continue; - - break; - } while(true); - - updateDebugState(); - } - else - { - applyForwardsChange(); + else + applyBackwardsChange(); updateDebugState(); } return true; } -void ShaderViewer::runToCursor() +void ShaderViewer::runToCursor(bool forward) { if(!m_Trace || m_States.empty()) return; @@ -1798,13 +1963,13 @@ void ShaderViewer::runToCursor() { if(fileMap.contains(i)) { - runTo(fileMap[i], true); + runTo(fileMap[i], forward); return; } } // if we didn't find one, just run - run(); + runTo({}, forward); } else { @@ -1815,7 +1980,7 @@ void ShaderViewer::runToCursor() int line = instructionForDisassemblyLine(i); if(line >= 0) { - runTo({(size_t)line}, true); + runTo({(size_t)line}, forward); break; } } @@ -1867,26 +2032,6 @@ const ShaderDebugState &ShaderViewer::GetNextState() const return m_States.back(); } -void ShaderViewer::runToSample() -{ - runTo({}, true, ShaderEvents::SampleLoadGather); -} - -void ShaderViewer::runToNanOrInf() -{ - runTo({}, true, ShaderEvents::GeneratedNanOrInf); -} - -void ShaderViewer::runBack() -{ - runTo({}, false); -} - -void ShaderViewer::run() -{ - runTo({}, true); -} - void ShaderViewer::runTo(QVector runToInstruction, bool forward, ShaderEvents condition) { if(!m_Trace || m_States.empty()) @@ -4097,7 +4242,7 @@ void ShaderViewer::RunForward() return; } - run(); + runTo({}, true); } void ShaderViewer::ShowErrors(const rdcstr &errors) diff --git a/qrenderdoc/Windows/ShaderViewer.h b/qrenderdoc/Windows/ShaderViewer.h index 45536994a..e90417e15 100644 --- a/qrenderdoc/Windows/ShaderViewer.h +++ b/qrenderdoc/Windows/ShaderViewer.h @@ -175,23 +175,17 @@ private slots: void disasm_tooltipShow(int x, int y); void disasm_tooltipHide(int x, int y); -public slots: - bool stepBack(); - bool stepNext(); - void runToCursor(); - void runToSample(); - void runToNanOrInf(); - void runBack(); - void run(); - private: explicit ShaderViewer(ICaptureContext &ctx, QWidget *parent = 0); void editShader(ResourceId id, ShaderStage stage, const QString &entryPoint, const rdcstrpairs &files, ShaderEncoding shaderEncoding, ShaderCompileFlags flags); void debugShader(const ShaderBindpointMapping *bind, const ShaderReflection *shader, ResourceId pipeline, ShaderDebugTrace *trace, const QString &debugContext); + bool eventFilter(QObject *watched, QEvent *event) override; + QAction *MakeExecuteAction(QString name, const QIcon &icon, QString tooltip, QKeySequence shortcut); + void MarkModification(); void PopulateCompileTools(); @@ -346,6 +340,16 @@ private: void setEditorWindowTitle(); + enum StepMode + { + StepInto, + StepOver, + StepOut, + }; + + bool step(bool forward, StepMode mode); + + void runToCursor(bool forward); void runTo(QVector runToInstructions, bool forward, ShaderEvents condition = ShaderEvents::NoEvent); diff --git a/qrenderdoc/Windows/ShaderViewer.ui b/qrenderdoc/Windows/ShaderViewer.ui index 44f4531c1..ad49456bb 100644 --- a/qrenderdoc/Windows/ShaderViewer.ui +++ b/qrenderdoc/Windows/ShaderViewer.ui @@ -117,136 +117,128 @@ - - - 20 - 310 - 256 - 192 - + + + 20 + 310 + 256 + 192 + + + + Qt::PreventContextMenu + + + QFrame::NoFrame + + + + 2 - - Qt::PreventContextMenu + + 0 - - QFrame::NoFrame + + 0 - - - 2 + + 0 + + + 0 + + + + + QFrame::NoFrame - + + true + + + + + + + + 0 + 0 + + + + Qt::PreventContextMenu + + + QFrame::NoFrame + + + 0 - - + + 0 - - + + 0 - - + + 0 - - - - - - 20 - 310 - 256 - 192 - - - - QFrame::NoFrame - - - true - + + + + + Sort accessed resource by shader binding + + + Sort By Resource + + + true + + + true + + + true + - - - - - Qt::PreventContextMenu - - - QFrame::NoFrame - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Sort By Resource - - - true - - - true - - - true - - - Sort accessed resource by shader binding - - - - - - - Sort By Instruction - - - true - - - false - - - true - - - Sort accessed resource by instruction step - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + + + + + Sort accessed resource by instruction step + + + Sort By Instruction + + + true + + + false + + + true + - - + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + @@ -385,16 +377,19 @@ - + - Run backwards (Shift-F5) + Run or step backwards in execution - Run backwards + Execute backwards... - :/control_start_blue.png:/control_start_blue.png + :/control_reverse_blue@2x.png:/control_reverse_blue@2x.png + + + QToolButton::MenuButtonPopup Qt::ToolButtonTextBesideIcon @@ -405,141 +400,19 @@ - + - Step Back (Shift-F10) + Run or step forwards in execution - Step Back - - - - :/control_reverse_blue.png:/control_reverse_blue.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Step Next (F10) - - - Step Next + Execute forwards... :/control_play_blue.png:/control_play_blue.png - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Qt::Vertical - - - - - - - Run forwards (F5) - - - Run forwards - - - - :/control_end_blue.png:/control_end_blue.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - - 23 - 22 - - - - Run to Cursor (Ctrl-F10) - - - Run to Cursor - - - - :/control_cursor_blue.png:/control_cursor_blue.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - - 23 - 22 - - - - Run to Sample/Load/Gather - - - Run to Sample - - - - :/control_sample_blue.png:/control_sample_blue.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - - 23 - 22 - - - - Run to NaN or Inf - - - Run to NaN/Inf - - - - :/control_nan_blue.png:/control_nan_blue.png + + QToolButton::MenuButtonPopup Qt::ToolButtonTextBesideIcon diff --git a/qrenderdoc/qrenderdoc_local.vcxproj b/qrenderdoc/qrenderdoc_local.vcxproj index d6d4ec66c..752c5c7f2 100644 --- a/qrenderdoc/qrenderdoc_local.vcxproj +++ b/qrenderdoc/qrenderdoc_local.vcxproj @@ -1947,8 +1947,16 @@ IF %ERRORLEVEL% NEQ 0 (echo ==================================================== + + + + + + + + @@ -1963,6 +1971,8 @@ IF %ERRORLEVEL% NEQ 0 (echo ==================================================== + + diff --git a/qrenderdoc/qrenderdoc_local.vcxproj.filters b/qrenderdoc/qrenderdoc_local.vcxproj.filters index 912c9dc70..870a2d9f5 100644 --- a/qrenderdoc/qrenderdoc_local.vcxproj.filters +++ b/qrenderdoc/qrenderdoc_local.vcxproj.filters @@ -1912,6 +1912,36 @@ Resources\Files + + Resources\Files + + + Resources\Files + + + Resources\Files + + + Resources\Files + + + Resources\Files + + + Resources\Files + + + Resources\Files + + + Resources\Files + + + Resources\Files + + + Resources\Files +