From 0b527fab49df60ac9c024f983e8de2e204a38514 Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 13 Dec 2017 16:40:44 +0000 Subject: [PATCH] Use rdc types instead of Qt containers in public QRenderDoc interface * This is to support python bindings - the pyside implementation of QVector, QString, etc is not available to SWIG, so SWIG treates these all as opaque types. * Rather than trying to set up bindings that work for rdcarray and QList/QVector, or implementing separate bindings, we instead just say that the public interface must use the rdc types. In most cases they seamlessly convert to/from Qt types anyway. * In a couple of places we use an array of pairs instead of a map. In future we probably want an rdcdict or rdcmap with proper dict bindings in python. --- qrenderdoc/Code/CaptureContext.cpp | 66 ++++----- qrenderdoc/Code/CaptureContext.h | 38 ++--- .../Code/Interface/CommonPipelineState.cpp | 133 ++++++++++-------- .../Code/Interface/CommonPipelineState.h | 67 ++++++--- .../Code/Interface/PersistantConfig.cpp | 87 +++++++----- qrenderdoc/Code/Interface/PersistantConfig.h | 97 ++++++++----- qrenderdoc/Code/Interface/QRDInterface.cpp | 4 +- qrenderdoc/Code/Interface/QRDInterface.h | 117 +++++++-------- qrenderdoc/Code/Interface/RemoteHost.cpp | 6 +- qrenderdoc/Code/Interface/RemoteHost.h | 15 +- qrenderdoc/Code/ReplayManager.cpp | 65 ++++----- qrenderdoc/Code/ReplayManager.h | 16 +-- .../Code/pyrenderdoc/container_handling.i | 49 +++++++ qrenderdoc/Code/pyrenderdoc/pyconversion.i | 1 + qrenderdoc/Code/pyrenderdoc/qrenderdoc.i | 9 ++ qrenderdoc/Code/pyrenderdoc/renderdoc.i | 5 + qrenderdoc/Windows/BufferViewer.cpp | 24 ++-- qrenderdoc/Windows/BufferViewer.h | 5 +- qrenderdoc/Windows/CommentView.cpp | 4 +- qrenderdoc/Windows/Dialogs/CaptureDialog.cpp | 24 ++-- qrenderdoc/Windows/Dialogs/CaptureDialog.h | 18 +-- qrenderdoc/Windows/Dialogs/LiveCapture.cpp | 18 +-- qrenderdoc/Windows/Dialogs/RemoteManager.cpp | 21 ++- qrenderdoc/Windows/Dialogs/SettingsDialog.cpp | 6 +- qrenderdoc/Windows/EventBrowser.cpp | 4 +- qrenderdoc/Windows/MainWindow.cpp | 37 +++-- qrenderdoc/Windows/MainWindow.h | 11 +- .../D3D11PipelineStateViewer.cpp | 16 +-- .../D3D12PipelineStateViewer.cpp | 16 +-- .../PipelineState/GLPipelineStateViewer.cpp | 15 +- .../PipelineState/PipelineStateViewer.cpp | 44 +++--- .../PipelineState/PipelineStateViewer.h | 4 +- .../VulkanPipelineStateViewer.cpp | 41 +++--- qrenderdoc/Windows/PythonShell.cpp | 35 ++--- qrenderdoc/Windows/ShaderViewer.cpp | 51 ++++--- qrenderdoc/Windows/ShaderViewer.h | 9 +- qrenderdoc/Windows/TextureViewer.cpp | 71 +++++----- qrenderdoc/Windows/TextureViewer.h | 16 +-- qrenderdoc/Windows/TimelineBar.cpp | 2 +- qrenderdoc/Windows/TimelineBar.h | 2 +- renderdoc/api/replay/basic_types.h | 38 +++++ renderdoc/api/replay/shader_types.h | 2 +- renderdoc/api/replay/structured_data.h | 4 +- 43 files changed, 754 insertions(+), 559 deletions(-) diff --git a/qrenderdoc/Code/CaptureContext.cpp b/qrenderdoc/Code/CaptureContext.cpp index 3b4beb59e..f5be034e2 100644 --- a/qrenderdoc/Code/CaptureContext.cpp +++ b/qrenderdoc/Code/CaptureContext.cpp @@ -103,7 +103,7 @@ bool CaptureContext::isRunning() return m_MainWindow && m_MainWindow->isVisible(); } -QString CaptureContext::TempCaptureFilename(QString appname) +rdcstr CaptureContext::TempCaptureFilename(const rdcstr &appname) { QString folder = Config().TemporaryCaptureDirectory; @@ -124,7 +124,7 @@ QString CaptureContext::TempCaptureFilename(QString appname) .arg(QDateTime::currentDateTimeUtc().toString(lit("yyyy.MM.dd_HH.mm.ss")))); } -void CaptureContext::LoadCapture(const QString &captureFile, const QString &origFilename, +void CaptureContext::LoadCapture(const rdcstr &captureFile, const rdcstr &origFilename, bool temporary, bool local) { m_LoadInProgress = true; @@ -160,7 +160,7 @@ void CaptureContext::LoadCapture(const QString &captureFile, const QString &orig m_CaptureMods = CaptureModifications::NoModifications; - QVector viewers(m_CaptureViewers); + rdcarray viewers(m_CaptureViewers); // make sure we're on a consistent event before invoking viewer forms if(m_LastDrawcall) @@ -691,7 +691,7 @@ void CaptureContext::RecompressCapture() QFile::rename(destFilename, GetCaptureFilename()); // and re-open - cap->OpenFile(GetCaptureFilename().toUtf8().data(), "rdc"); + cap->OpenFile(GetCaptureFilename().c_str(), "rdc"); } else { @@ -717,7 +717,7 @@ void CaptureContext::RecompressCapture() QFile::remove(tempFilename); } -bool CaptureContext::SaveCaptureTo(const QString &captureFile) +bool CaptureContext::SaveCaptureTo(const rdcstr &captureFile) { bool success = false; QString error; @@ -737,7 +737,7 @@ bool CaptureContext::SaveCaptureTo(const QString &captureFile) if(capFile) { // this will overwrite - success = capFile->CopyFileTo(captureFile.toUtf8().data()); + success = capFile->CopyFileTo(captureFile.c_str()); } else { @@ -828,7 +828,7 @@ void CaptureContext::CloseCapture() m_CaptureLoaded = false; - QVector capviewers(m_CaptureViewers); + rdcarray capviewers(m_CaptureViewers); for(ICaptureViewer *viewer : capviewers) { @@ -837,7 +837,7 @@ void CaptureContext::CloseCapture() } } -void CaptureContext::SetEventID(const QVector &exclude, uint32_t selectedEventID, +void CaptureContext::SetEventID(const rdcarray &exclude, uint32_t selectedEventID, uint32_t eventID, bool force) { uint32_t prevSelectedEventID = m_SelectedEventID; @@ -861,7 +861,7 @@ void CaptureContext::SetEventID(const QVector &exclude, uint32 RefreshUIStatus(exclude, updateSelectedEvent, updateEvent); } -void CaptureContext::RefreshUIStatus(const QVector &exclude, +void CaptureContext::RefreshUIStatus(const rdcarray &exclude, bool updateSelectedEvent, bool updateEvent) { for(ICaptureViewer *viewer : m_CaptureViewers) @@ -888,7 +888,7 @@ void CaptureContext::AddMessages(const rdcarray &msgs) } } -void CaptureContext::SetNotes(const QString &key, const QString &contents) +void CaptureContext::SetNotes(const rdcstr &key, const rdcstr &contents) { // ignore no-op changes if(m_Notes.contains(key) && m_Notes[key] == contents) @@ -1072,7 +1072,7 @@ void CaptureContext::LoadNotes(const QString &data) } } -QString CaptureContext::GetResourceName(ResourceId id) +rdcstr CaptureContext::GetResourceName(ResourceId id) { if(id == ResourceId()) return tr("No Resource"); @@ -1111,7 +1111,7 @@ bool CaptureContext::HasResourceCustomName(ResourceId id) return m_CustomNames.contains(id); } -void CaptureContext::SetResourceCustomName(ResourceId id, const QString &name) +void CaptureContext::SetResourceCustomName(ResourceId id, const rdcstr &name) { if(name.isEmpty()) { @@ -1244,11 +1244,11 @@ ICaptureDialog *CaptureContext::GetCaptureDialog() m_CaptureDialog = new CaptureDialog( *this, [this](const QString &exe, const QString &workingDir, const QString &cmdLine, - const QList &env, CaptureOptions opts, + const rdcarray &env, CaptureOptions opts, std::function callback) { return m_MainWindow->OnCaptureTrigger(exe, workingDir, cmdLine, env, opts, callback); }, - [this](uint32_t PID, const QList &env, const QString &name, + [this](uint32_t PID, const rdcarray &env, const QString &name, CaptureOptions opts, std::function callback) { return m_MainWindow->OnInjectTrigger(PID, env, name, opts, callback); }, @@ -1408,8 +1408,8 @@ void CaptureContext::ShowResourceInspector() m_MainWindow->showResourceInspector(); } -IShaderViewer *CaptureContext::EditShader(bool customShader, const QString &entryPoint, - const QStringMap &files, +IShaderViewer *CaptureContext::EditShader(bool customShader, const rdcstr &entryPoint, + const rdcstrpairs &files, IShaderViewer::SaveCallback saveCallback, IShaderViewer::CloseCallback closeCallback) { @@ -1419,7 +1419,7 @@ IShaderViewer *CaptureContext::EditShader(bool customShader, const QString &entr IShaderViewer *CaptureContext::DebugShader(const ShaderBindpointMapping *bind, const ShaderReflection *shader, ResourceId pipeline, - ShaderDebugTrace *trace, const QString &debugContext) + ShaderDebugTrace *trace, const rdcstr &debugContext) { return ShaderViewer::DebugShader(*this, bind, shader, pipeline, trace, debugContext, m_MainWindow->Widget()); @@ -1431,7 +1431,7 @@ IShaderViewer *CaptureContext::ViewShader(const ShaderReflection *shader, Resour } IBufferViewer *CaptureContext::ViewBuffer(uint64_t byteOffset, uint64_t byteSize, ResourceId id, - const QString &format) + const rdcstr &format) { BufferViewer *viewer = new BufferViewer(*this, false, m_MainWindow); @@ -1441,7 +1441,7 @@ IBufferViewer *CaptureContext::ViewBuffer(uint64_t byteOffset, uint64_t byteSize } IBufferViewer *CaptureContext::ViewTextureAsBuffer(uint32_t arrayIdx, uint32_t mip, ResourceId id, - const QString &format) + const rdcstr &format) { BufferViewer *viewer = new BufferViewer(*this, false, m_MainWindow); @@ -1466,57 +1466,57 @@ IPixelHistoryView *CaptureContext::ViewPixelHistory(ResourceId texID, int x, int return new PixelHistoryView(*this, texID, QPoint(x, y), display, m_MainWindow); } -QWidget *CaptureContext::CreateBuiltinWindow(const QString &objectName) +QWidget *CaptureContext::CreateBuiltinWindow(const rdcstr &objectName) { - if(objectName == lit("textureViewer")) + if(objectName == "textureViewer") { return GetTextureViewer()->Widget(); } - else if(objectName == lit("eventBrowser")) + else if(objectName == "eventBrowser") { return GetEventBrowser()->Widget(); } - else if(objectName == lit("pipelineViewer")) + else if(objectName == "pipelineViewer") { return GetPipelineViewer()->Widget(); } - else if(objectName == lit("meshPreview")) + else if(objectName == "meshPreview") { return GetMeshPreview()->Widget(); } - else if(objectName == lit("apiInspector")) + else if(objectName == "apiInspector") { return GetAPIInspector()->Widget(); } - else if(objectName == lit("capDialog")) + else if(objectName == "capDialog") { return GetCaptureDialog()->Widget(); } - else if(objectName == lit("debugMessageView")) + else if(objectName == "debugMessageView") { return GetDebugMessageView()->Widget(); } - else if(objectName == lit("commentView")) + else if(objectName == "commentView") { return GetCommentView()->Widget(); } - else if(objectName == lit("statisticsViewer")) + else if(objectName == "statisticsViewer") { return GetStatisticsViewer()->Widget(); } - else if(objectName == lit("timelineBar")) + else if(objectName == "timelineBar") { return GetTimelineBar()->Widget(); } - else if(objectName == lit("pythonShell")) + else if(objectName == "pythonShell") { return GetPythonShell()->Widget(); } - else if(objectName == lit("resourceInspector")) + else if(objectName == "resourceInspector") { return GetResourceInspector()->Widget(); } - else if(objectName == lit("performanceCounterViewer")) + else if(objectName == "performanceCounterViewer") { return GetPerformanceCounterViewer()->Widget(); } diff --git a/qrenderdoc/Code/CaptureContext.h b/qrenderdoc/Code/CaptureContext.h index dd0313efc..38eabb445 100644 --- a/qrenderdoc/Code/CaptureContext.h +++ b/qrenderdoc/Code/CaptureContext.h @@ -63,22 +63,22 @@ public: bool isRunning(); - QString TempCaptureFilename(QString appname) override; + rdcstr TempCaptureFilename(const rdcstr &appname) override; ////////////////////////////////////////////////////////////////////////////// // Control functions - void LoadCapture(const QString &captureFile, const QString &origFilename, bool temporary, + void LoadCapture(const rdcstr &captureFile, const rdcstr &origFilename, bool temporary, bool local) override; - bool SaveCaptureTo(const QString &captureFile) override; + bool SaveCaptureTo(const rdcstr &captureFile) override; void RecompressCapture() override; void CloseCapture() override; - void SetEventID(const QVector &exclude, uint32_t selectedEventID, + void SetEventID(const rdcarray &exclude, uint32_t selectedEventID, uint32_t eventID, bool force = false) override; void RefreshStatus() override { SetEventID({}, m_SelectedEventID, m_EventID, true); } - void RefreshUIStatus(const QVector &exclude, bool updateSelectedEvent, + void RefreshUIStatus(const rdcarray &exclude, bool updateSelectedEvent, bool updateEvent); void AddCaptureViewer(ICaptureViewer *f) override @@ -101,7 +101,7 @@ public: bool IsCaptureLocal() override { return m_CaptureLocal; } bool IsCaptureTemporary() override { return m_CaptureTemporary; } bool IsCaptureLoading() override { return m_LoadInProgress; } - QString GetCaptureFilename() override { return m_CaptureFile; } + rdcstr GetCaptureFilename() override { return m_CaptureFile; } CaptureModifications GetCaptureModifications() override { return m_CaptureMods; } const FrameDescription &FrameInfo() override { return m_FrameInfo; } const APIProperties &APIProps() override { return m_APIProps; } @@ -117,10 +117,10 @@ public: const rdcarray &CurDrawcalls() override { return m_Drawcalls; } ResourceDescription *GetResource(ResourceId id) override { return m_Resources[id]; } const rdcarray &GetResources() override { return m_ResourceList; } - QString GetResourceName(ResourceId id) override; + rdcstr GetResourceName(ResourceId id) override; bool IsAutogeneratedName(ResourceId id) override; bool HasResourceCustomName(ResourceId id) override; - void SetResourceCustomName(ResourceId id, const QString &name) override; + void SetResourceCustomName(ResourceId id, const rdcstr &name) override; int ResourceNameCacheID() override; TextureDescription *GetTexture(ResourceId id) override { return m_Textures[id]; } const rdcarray &GetTextures() override { return m_TextureList; } @@ -134,14 +134,14 @@ public: WindowingSystem CurWindowingSystem() override { return m_CurWinSystem; } void *FillWindowingData(uintptr_t winId) override; - const QVector &DebugMessages() override { return m_DebugMessages; } + const rdcarray &DebugMessages() override { return m_DebugMessages; } int UnreadMessageCount() override { return m_UnreadMessageCount; } void MarkMessagesRead() override { m_UnreadMessageCount = 0; } void AddMessages(const rdcarray &msgs) override; - QString GetNotes(const QString &key) override { return m_Notes[key]; } - void SetNotes(const QString &key, const QString &contents) override; - QList GetBookmarks() override { return m_Bookmarks; } + rdcstr GetNotes(const rdcstr &key) override { return m_Notes[key]; } + void SetNotes(const rdcstr &key, const rdcstr &contents) override; + rdcarray GetBookmarks() override { return m_Bookmarks; } void SetBookmark(const EventBookmark &mark) override; void RemoveBookmark(uint32_t EID) override; @@ -187,27 +187,27 @@ public: void ShowPythonShell() override; void ShowResourceInspector() override; - IShaderViewer *EditShader(bool customShader, const QString &entryPoint, const QStringMap &files, + IShaderViewer *EditShader(bool customShader, const rdcstr &entryPoint, const rdcstrpairs &files, IShaderViewer::SaveCallback saveCallback, IShaderViewer::CloseCallback closeCallback) override; IShaderViewer *DebugShader(const ShaderBindpointMapping *bind, const ShaderReflection *shader, ResourceId pipeline, ShaderDebugTrace *trace, - const QString &debugContext) override; + const rdcstr &debugContext) override; IShaderViewer *ViewShader(const ShaderReflection *shader, ResourceId pipeline) override; IBufferViewer *ViewBuffer(uint64_t byteOffset, uint64_t byteSize, ResourceId id, - const QString &format = QString()) override; + const rdcstr &format = "") override; IBufferViewer *ViewTextureAsBuffer(uint32_t arrayIdx, uint32_t mip, ResourceId id, - const QString &format = QString()) override; + const rdcstr &format = "") override; IConstantBufferPreviewer *ViewConstantBuffer(ShaderStage stage, uint32_t slot, uint32_t idx) override; IPixelHistoryView *ViewPixelHistory(ResourceId texID, int x, int y, const TextureDisplay &display) override; - QWidget *CreateBuiltinWindow(const QString &objectName) override; + QWidget *CreateBuiltinWindow(const rdcstr &objectName) override; void BuiltinWindowClosed(QWidget *window) override; void RaiseDockWindow(QWidget *dockWindow) override; @@ -243,7 +243,7 @@ private: QString m_CaptureFile; CaptureModifications m_CaptureMods = CaptureModifications::NoModifications; - QVector m_DebugMessages; + rdcarray m_DebugMessages; int m_UnreadMessageCount = 0; bool PassEquivalent(const DrawcallDescription &a, const DrawcallDescription &b); @@ -306,7 +306,7 @@ private: QList m_Bookmarks; - QStringMap m_Notes; + QMap m_Notes; QMap m_CustomNames; int m_CustomNameCachedID = 1; diff --git a/qrenderdoc/Code/Interface/CommonPipelineState.cpp b/qrenderdoc/Code/Interface/CommonPipelineState.cpp index 22c781435..a6fcbbcc4 100644 --- a/qrenderdoc/Code/Interface/CommonPipelineState.cpp +++ b/qrenderdoc/Code/Interface/CommonPipelineState.cpp @@ -26,7 +26,7 @@ #include "Code/QRDUtils.h" #include "QRDInterface.h" -QString CommonPipelineState::GetResourceLayout(ResourceId id) +rdcstr CommonPipelineState::GetResourceLayout(ResourceId id) { if(IsCaptureLoaded()) { @@ -52,7 +52,7 @@ QString CommonPipelineState::GetResourceLayout(ResourceId id) return lit("Unknown"); } -QString CommonPipelineState::Abbrev(ShaderStage stage) +rdcstr CommonPipelineState::Abbrev(ShaderStage stage) { if(IsCaptureD3D11() || (!IsCaptureLoaded() && DefaultType == GraphicsAPI::D3D11) || IsCaptureD3D12() || (!IsCaptureLoaded() && DefaultType == GraphicsAPI::D3D12)) @@ -86,7 +86,7 @@ QString CommonPipelineState::Abbrev(ShaderStage stage) return lit("?S"); } -QString CommonPipelineState::OutputAbbrev() +rdcstr CommonPipelineState::OutputAbbrev() { if(IsCaptureGL() || (!IsCaptureLoaded() && DefaultType == GraphicsAPI::OpenGL) || IsCaptureVK() || (!IsCaptureLoaded() && DefaultType == GraphicsAPI::Vulkan)) @@ -173,7 +173,7 @@ const VKPipe::Shader &CommonPipelineState::GetVulkanStage(ShaderStage stage) return m_Vulkan->m_CS; } -QString CommonPipelineState::GetShaderExtension() +rdcstr CommonPipelineState::GetShaderExtension() { if(IsCaptureGL() || (!IsCaptureLoaded() && DefaultType == GraphicsAPI::OpenGL) || IsCaptureVK() || (!IsCaptureLoaded() && DefaultType == GraphicsAPI::Vulkan)) @@ -379,7 +379,7 @@ ResourceId CommonPipelineState::GetGraphicsPipelineObject() return ResourceId(); } -QString CommonPipelineState::GetShaderEntryPoint(ShaderStage stage) +rdcstr CommonPipelineState::GetShaderEntryPoint(ShaderStage stage) { if(IsCaptureLoaded() && IsCaptureVK()) { @@ -395,7 +395,7 @@ QString CommonPipelineState::GetShaderEntryPoint(ShaderStage stage) } } - return QString(); + return ""; } ResourceId CommonPipelineState::GetShader(ShaderStage stage) @@ -459,7 +459,7 @@ ResourceId CommonPipelineState::GetShader(ShaderStage stage) return ResourceId(); } -QString CommonPipelineState::GetShaderName(ShaderStage stage) +rdcstr CommonPipelineState::GetShaderName(ShaderStage stage) { if(IsCaptureLoaded()) { @@ -517,10 +517,10 @@ QString CommonPipelineState::GetShaderName(ShaderStage stage) } } - return QString(); + return ""; } -QPair CommonPipelineState::GetIBuffer() +BoundBuffer CommonPipelineState::GetIBuffer() { ResourceId buf; uint64_t ByteOffset = 0; @@ -549,7 +549,11 @@ QPair CommonPipelineState::GetIBuffer() } } - return qMakePair(buf, ByteOffset); + BoundBuffer ret; + ret.Buffer = buf; + ret.ByteOffset = ByteOffset; + + return ret; } bool CommonPipelineState::IsStripRestartEnabled() @@ -600,9 +604,9 @@ uint32_t CommonPipelineState::GetStripRestartIndex() return UINT32_MAX; } -QVector CommonPipelineState::GetVBuffers() +rdcarray CommonPipelineState::GetVBuffers() { - QVector ret; + rdcarray ret; if(IsCaptureLoaded()) { @@ -652,7 +656,7 @@ QVector CommonPipelineState::GetVBuffers() return ret; } -QVector CommonPipelineState::GetVertexInputs() +rdcarray CommonPipelineState::GetVertexInputs() { if(IsCaptureLoaded()) { @@ -660,9 +664,10 @@ QVector CommonPipelineState::GetVertexInputs() { uint32_t byteOffs[128] = {}; - auto &layouts = m_D3D11->m_IA.layouts; + const rdcarray &layouts = m_D3D11->m_IA.layouts; - QVector ret(layouts.count()); + rdcarray ret; + ret.resize(layouts.size()); for(int i = 0; i < layouts.count(); i++) { QString semName = layouts[i].SemanticName; @@ -718,9 +723,10 @@ QVector CommonPipelineState::GetVertexInputs() { uint32_t byteOffs[128] = {}; - auto &layouts = m_D3D12->m_IA.layouts; + const rdcarray &layouts = m_D3D12->m_IA.layouts; - QVector ret(layouts.count()); + rdcarray ret; + ret.resize(layouts.size()); for(int i = 0; i < layouts.count(); i++) { QString semName = layouts[i].SemanticName; @@ -728,7 +734,7 @@ QVector CommonPipelineState::GetVertexInputs() bool needsSemanticIdx = false; for(int j = 0; j < layouts.count(); j++) { - if(i != j && !semName.compare(layouts[j].SemanticName, Qt::CaseInsensitive)) + if(i != j && !semName.compare(QString(layouts[j].SemanticName), Qt::CaseInsensitive)) { needsSemanticIdx = true; break; @@ -774,7 +780,7 @@ QVector CommonPipelineState::GetVertexInputs() } else if(IsCaptureGL()) { - auto &attrs = m_GL->m_VtxIn.attributes; + const rdcarray &attrs = m_GL->m_VtxIn.attributes; int num = 0; for(int i = 0; i < attrs.count(); i++) @@ -790,7 +796,8 @@ QVector CommonPipelineState::GetVertexInputs() } int a = 0; - QVector ret(attrs.count()); + rdcarray ret; + ret.resize(attrs.count()); for(int i = 0; i < attrs.count() && a < num; i++) { ret[a].Name = lit("attr%1").arg(i); @@ -851,7 +858,7 @@ QVector CommonPipelineState::GetVertexInputs() } else if(IsCaptureVK()) { - auto &attrs = m_Vulkan->VI.attrs; + const rdcarray &attrs = m_Vulkan->VI.attrs; int num = 0; for(int i = 0; i < attrs.count(); i++) @@ -870,7 +877,8 @@ QVector CommonPipelineState::GetVertexInputs() } int a = 0; - QVector ret(num); + rdcarray ret; + ret.resize(num); for(int i = 0; i < attrs.count() && a < num; i++) { ret[a].Name = lit("attr%1").arg(i); @@ -906,7 +914,7 @@ QVector CommonPipelineState::GetVertexInputs() } } - return QVector(); + return rdcarray(); } BoundCBuffer CommonPipelineState::GetConstantBuffer(ShaderStage stage, uint32_t BufIdx, @@ -997,7 +1005,8 @@ BoundCBuffer CommonPipelineState::GetConstantBuffer(ShaderStage stage, uint32_t return ret; } - auto &descriptorBind = pipe.DescSets[bind.bindset].bindings[bind.bind].binds[ArrayIdx]; + const VKPipe::BindingElement &descriptorBind = + pipe.DescSets[bind.bindset].bindings[bind.bind].binds[ArrayIdx]; buf = descriptorBind.res; ByteOffset = descriptorBind.offset; @@ -1015,9 +1024,9 @@ BoundCBuffer CommonPipelineState::GetConstantBuffer(ShaderStage stage, uint32_t return ret; } -QMap> CommonPipelineState::GetReadOnlyResources(ShaderStage stage) +rdcarray CommonPipelineState::GetReadOnlyResources(ShaderStage stage) { - QMap> ret; + rdcarray ret; if(IsCaptureLoaded()) { @@ -1025,6 +1034,8 @@ QMap> CommonPipelineState::GetReadOnlyResou { const D3D11Pipe::Shader &s = GetD3D11Stage(stage); + ret.reserve(s.SRVs.size()); + for(int i = 0; i < s.SRVs.count(); i++) { BindpointMap key(0, i); @@ -1035,7 +1046,7 @@ QMap> CommonPipelineState::GetReadOnlyResou val.FirstSlice = (int)s.SRVs[i].FirstArraySlice; val.typeHint = s.SRVs[i].Format.compType; - ret[key] = {val}; + ret.push_back(BoundResourceArray(key, {val})); } return ret; @@ -1062,7 +1073,7 @@ QMap> CommonPipelineState::GetReadOnlyResou val.FirstSlice = (int)bind.FirstArraySlice; val.typeHint = bind.Format.compType; - ret[key] = {val}; + ret.push_back(BoundResourceArray(key, {val})); } } @@ -1070,6 +1081,8 @@ QMap> CommonPipelineState::GetReadOnlyResou } else if(IsCaptureGL()) { + ret.reserve(m_GL->Textures.size()); + for(int i = 0; i < m_GL->Textures.count(); i++) { BindpointMap key(0, i); @@ -1080,30 +1093,33 @@ QMap> CommonPipelineState::GetReadOnlyResou val.FirstSlice = (int)m_GL->Textures[i].FirstSlice; val.typeHint = CompType::Typeless; - ret[key] = {val}; + ret.push_back(BoundResourceArray(key, {val})); } return ret; } else if(IsCaptureVK()) { - const auto &descsets = + const rdcarray &descsets = stage == ShaderStage::Compute ? m_Vulkan->compute.DescSets : m_Vulkan->graphics.DescSets; ShaderStageMask mask = MaskForStage(stage); for(int set = 0; set < descsets.count(); set++) { - const auto &descset = descsets[set]; + const VKPipe::DescriptorSet &descset = descsets[set]; for(int slot = 0; slot < descset.bindings.count(); slot++) { - const auto &bind = descset.bindings[slot]; + const VKPipe::DescriptorBinding &bind = descset.bindings[slot]; if((bind.type == BindType::ImageSampler || bind.type == BindType::InputAttachment || bind.type == BindType::ReadOnlyImage || bind.type == BindType::ReadOnlyTBuffer) && (bind.stageFlags & mask) == mask) { - BindpointMap key(set, slot); - QVector val(bind.descriptorCount); + ret.push_back(BoundResourceArray()); + ret.back().BindPoint = BindpointMap(set, slot); + + rdcarray &val = ret.back().Resources; + val.resize(bind.descriptorCount); for(uint32_t i = 0; i < bind.descriptorCount; i++) { @@ -1112,8 +1128,6 @@ QMap> CommonPipelineState::GetReadOnlyResou val[i].FirstSlice = (int)bind.binds[i].baseLayer; val[i].typeHint = bind.binds[i].viewfmt.compType; } - - ret[key] = val; } } } @@ -1125,9 +1139,9 @@ QMap> CommonPipelineState::GetReadOnlyResou return ret; } -QMap> CommonPipelineState::GetReadWriteResources(ShaderStage stage) +rdcarray CommonPipelineState::GetReadWriteResources(ShaderStage stage) { - QMap> ret; + rdcarray ret; if(IsCaptureLoaded()) { @@ -1135,6 +1149,8 @@ QMap> CommonPipelineState::GetReadWriteReso { if(stage == ShaderStage::Compute) { + ret.reserve(m_D3D11->m_CS.UAVs.size()); + for(int i = 0; i < m_D3D11->m_CS.UAVs.count(); i++) { BindpointMap key(0, i); @@ -1145,20 +1161,22 @@ QMap> CommonPipelineState::GetReadWriteReso val.FirstSlice = (int)m_D3D11->m_CS.UAVs[i].FirstArraySlice; val.typeHint = m_D3D11->m_CS.UAVs[i].Format.compType; - ret[key] = {val}; + ret.push_back(BoundResourceArray(key, {val})); } } else { int uavstart = (int)m_D3D11->m_OM.UAVStartSlot; + ret.reserve(m_D3D11->m_OM.UAVs.size() + qMax(0, uavstart)); + // up to UAVStartSlot treat these bindings as empty. for(int i = 0; i < uavstart; i++) { BindpointMap key(0, i); BoundResource val; - ret[key] = {val}; + ret.push_back(BoundResourceArray(key, {val})); } for(int i = 0; i < m_D3D11->m_OM.UAVs.count() - uavstart; i++) @@ -1171,7 +1189,7 @@ QMap> CommonPipelineState::GetReadWriteReso val.FirstSlice = (int)m_D3D11->m_OM.UAVs[i].FirstArraySlice; val.typeHint = m_D3D11->m_OM.UAVs[i].Format.compType; - ret[key] = {val}; + ret.push_back(BoundResourceArray(key, {val})); } } } @@ -1197,12 +1215,14 @@ QMap> CommonPipelineState::GetReadWriteReso val.FirstSlice = (int)bind.FirstArraySlice; val.typeHint = bind.Format.compType; - ret[key] = {val}; + ret.push_back(BoundResourceArray(key, {val})); } } } else if(IsCaptureGL()) { + ret.reserve(m_GL->Images.size()); + for(int i = 0; i < m_GL->Images.count(); i++) { BindpointMap key(0, i); @@ -1213,28 +1233,31 @@ QMap> CommonPipelineState::GetReadWriteReso val.FirstSlice = (int)m_GL->Images[i].Layer; val.typeHint = m_GL->Images[i].Format.compType; - ret[key] = {val}; + ret.push_back(BoundResourceArray(key, {val})); } } else if(IsCaptureVK()) { - const auto &descsets = + const rdcarray &descsets = stage == ShaderStage::Compute ? m_Vulkan->compute.DescSets : m_Vulkan->graphics.DescSets; ShaderStageMask mask = MaskForStage(stage); for(int set = 0; set < descsets.count(); set++) { - const auto &descset = descsets[set]; + const VKPipe::DescriptorSet &descset = descsets[set]; for(int slot = 0; slot < descset.bindings.count(); slot++) { - const auto &bind = descset.bindings[slot]; + const VKPipe::DescriptorBinding &bind = descset.bindings[slot]; if((bind.type == BindType::ReadWriteBuffer || bind.type == BindType::ReadWriteImage || bind.type == BindType::ReadWriteTBuffer) && (bind.stageFlags & mask) == mask) { - BindpointMap key(set, slot); - QVector val(bind.descriptorCount); + ret.push_back(BoundResourceArray()); + ret.back().BindPoint = BindpointMap(set, slot); + + rdcarray &val = ret.back().Resources; + val.resize(bind.descriptorCount); for(uint32_t i = 0; i < bind.descriptorCount; i++) { @@ -1243,8 +1266,6 @@ QMap> CommonPipelineState::GetReadWriteReso val[i].FirstSlice = (int)bind.binds[i].baseLayer; val[i].typeHint = bind.binds[i].viewfmt.compType; } - - ret[key] = val; } } } @@ -1287,8 +1308,8 @@ BoundResource CommonPipelineState::GetDepthTarget() } else if(IsCaptureVK()) { - const auto &rp = m_Vulkan->Pass.renderpass; - const auto &fb = m_Vulkan->Pass.framebuffer; + const VKPipe::RenderPass &rp = m_Vulkan->Pass.renderpass; + const VKPipe::Framebuffer &fb = m_Vulkan->Pass.framebuffer; if(rp.depthstencilAttachment >= 0 && rp.depthstencilAttachment < fb.attachments.count()) { @@ -1307,9 +1328,9 @@ BoundResource CommonPipelineState::GetDepthTarget() return BoundResource(); } -QVector CommonPipelineState::GetOutputTargets() +rdcarray CommonPipelineState::GetOutputTargets() { - QVector ret; + rdcarray ret; if(IsCaptureLoaded()) { @@ -1353,8 +1374,8 @@ QVector CommonPipelineState::GetOutputTargets() } else if(IsCaptureVK()) { - const auto &rp = m_Vulkan->Pass.renderpass; - const auto &fb = m_Vulkan->Pass.framebuffer; + const VKPipe::RenderPass &rp = m_Vulkan->Pass.renderpass; + const VKPipe::Framebuffer &fb = m_Vulkan->Pass.framebuffer; int idx = 0; diff --git a/qrenderdoc/Code/Interface/CommonPipelineState.h b/qrenderdoc/Code/Interface/CommonPipelineState.h index f68945103..e740e5d38 100644 --- a/qrenderdoc/Code/Interface/CommonPipelineState.h +++ b/qrenderdoc/Code/Interface/CommonPipelineState.h @@ -60,18 +60,43 @@ struct BoundResource DECLARE_REFLECTION_STRUCT(BoundResource); -DOCUMENT("Information about a single vertex buffer binding."); -struct BoundVBuffer +// TODO this should be replaced with an rdcmap +DOCUMENT(R"(Contains all of the bound resources at a particular bindpoint. In APIs that don't +support resource arrays, there will only be one bound resource. +)"); +struct BoundResourceArray +{ + BoundResourceArray() = default; + BoundResourceArray(BindpointMap b) : BindPoint(b) {} + BoundResourceArray(BindpointMap b, const rdcarray &r) : BindPoint(b), Resources(r) + { + } + + // for convenience for searching the array, we compare only using the BindPoint + bool operator==(const BoundResourceArray &o) const { return BindPoint == o.BindPoint; } + bool operator!=(const BoundResourceArray &o) const { return !(BindPoint == o.BindPoint); } + bool operator<(const BoundResourceArray &o) const { return BindPoint < o.BindPoint; } + DOCUMENT("The bind point for this array of bound resources."); + BindpointMap BindPoint; + + DOCUMENT("The resources at this bind point"); + rdcarray Resources; +}; + +DECLARE_REFLECTION_STRUCT(BoundResourceArray); + +DOCUMENT("Information about a single vertex or index buffer binding."); +struct BoundBuffer { DOCUMENT("A :class:`~renderdoc.ResourceId` identifying the buffer."); ResourceId Buffer; - DOCUMENT("The offset in bytes from the start of the buffer to the vertex data."); + DOCUMENT("The offset in bytes from the start of the buffer to the data."); uint64_t ByteOffset = 0; - DOCUMENT("The stride in bytes between the start of one vertex and the start of the next."); + DOCUMENT("The stride in bytes between the start of one element and the start of the next."); uint32_t ByteStride = 0; }; -DECLARE_REFLECTION_STRUCT(BoundVBuffer); +DECLARE_REFLECTION_STRUCT(BoundBuffer); DOCUMENT("Information about a single constant buffer binding."); struct BoundCBuffer @@ -90,7 +115,7 @@ DOCUMENT("Information about a vertex input attribute feeding the vertex shader." struct VertexInputAttribute { DOCUMENT("The name of this input. This may be a variable name or a semantic name."); - QString Name; + rdcstr Name; DOCUMENT("The index of the vertex buffer used to provide this attribute."); int VertexBuffer; DOCUMENT("The byte offset from the start of the vertex data for this VB to this attribute."); @@ -267,7 +292,7 @@ requirements. :return: The name of the current resource layout. :rtype: ``str`` )"); - QString GetResourceLayout(ResourceId id); + rdcstr GetResourceLayout(ResourceId id); DOCUMENT(R"(Retrieves a suitable two or three letter abbreviation of the given shader stage. @@ -275,14 +300,14 @@ requirements. :return: The abbreviation of the stage. :rtype: ``str`` )"); - QString Abbrev(ShaderStage stage); + rdcstr Abbrev(ShaderStage stage); DOCUMENT(R"(Retrieves a suitable two or three letter abbreviation of the output stage. Typically 'OM' or 'FBO'. :return: The abbreviation of the output stage. :rtype: ``str`` )"); - QString OutputAbbrev(); + rdcstr OutputAbbrev(); DOCUMENT(R"(Retrieves the viewport for a given index. @@ -334,7 +359,7 @@ For some APIs that don't distinguish by entry point, this may be empty. :return: The entry point name for the given shader. :rtype: ``str`` )"); - QString GetShaderEntryPoint(ShaderStage stage); + rdcstr GetShaderEntryPoint(ShaderStage stage); DOCUMENT(R"(Retrieves the object ID of the shader bound at a shader stage. @@ -350,7 +375,7 @@ For some APIs that don't distinguish by entry point, this may be empty. :return: The object name for the given shader. :rtype: ``str`` )"); - QString GetShaderName(ShaderStage stage); + rdcstr GetShaderName(ShaderStage stage); DOCUMENT(R"(Retrieves the common file extension for high level shaders in the current API. @@ -359,7 +384,7 @@ Typically this is ``glsl`` or ``hlsl``. :return: The file extension with no ``.``. :rtype: ``str`` )"); - QString GetShaderExtension(); + rdcstr GetShaderExtension(); DOCUMENT(R"(Retrieves the current index buffer binding. @@ -367,7 +392,7 @@ Typically this is ``glsl`` or ``hlsl``. start of the index data. :rtype: ``tuple`` of :class:`~renderdoc.ResourceId` and ``int`` )"); - QPair GetIBuffer(); + BoundBuffer GetIBuffer(); DOCUMENT(R"(Determines whether or not primitive restart is enabled. @@ -387,16 +412,16 @@ Typically this is ``glsl`` or ``hlsl``. DOCUMENT(R"(Retrieves the currently bound vertex buffers. :return: The list of bound vertex buffers. -:rtype: ``list`` of :class:`BoundVBuffer`. +:rtype: ``list`` of :class:`BoundBuffer`. )"); - QVector GetVBuffers(); + rdcarray GetVBuffers(); DOCUMENT(R"(Retrieves the currently specified vertex attributes. :return: The list of current vertex attributes. :rtype: ``list`` of :class:`VertexInputAttribute`. )"); - QVector GetVertexInputs(); + rdcarray GetVertexInputs(); DOCUMENT(R"(Retrieves the constant buffer at a given binding. @@ -413,17 +438,17 @@ Typically this is ``glsl`` or ``hlsl``. :param ~renderdoc.ShaderStage stage: The shader stage to fetch from. :return: The currently bound read-only resoruces. -:rtype: ``dict`` with :class:`~renderdoc.BindpointMap` keys, to lists of :class:`BoundResource`. +:rtype: ``list`` of :class:`BoundResourceArray` entries )"); - QMap> GetReadOnlyResources(ShaderStage stage); + rdcarray GetReadOnlyResources(ShaderStage stage); DOCUMENT(R"(Retrieves the read/write resources bound to a particular shader stage. :param ~renderdoc.ShaderStage stage: The shader stage to fetch from. :return: The currently bound read/write resoruces. -:rtype: ``dict`` with :class:`~renderdoc.BindpointMap` keys, to lists of :class:`BoundResource`. +:rtype: ``list`` of :class:`BoundResourceArray` entries )"); - QMap> GetReadWriteResources(ShaderStage stage); + rdcarray GetReadWriteResources(ShaderStage stage); DOCUMENT(R"(Retrieves the read/write resources bound to the depth-stencil output. @@ -437,7 +462,7 @@ Typically this is ``glsl`` or ``hlsl``. :return: The currently bound output targets. :rtype: ``list`` of :class:`BoundResource`. )"); - QVector GetOutputTargets(); + rdcarray GetOutputTargets(); private: const D3D11Pipe::State *m_D3D11 = NULL; diff --git a/qrenderdoc/Code/Interface/PersistantConfig.cpp b/qrenderdoc/Code/Interface/PersistantConfig.cpp index 015549849..85189dbe3 100644 --- a/qrenderdoc/Code/Interface/PersistantConfig.cpp +++ b/qrenderdoc/Code/Interface/PersistantConfig.cpp @@ -40,7 +40,7 @@ variantType convertToVariant(const origType &val) } template -variantType convertToVariant(const QList &val) +variantType convertToVariant(const rdcarray &val) { variantType ret; ret.reserve(val.count()); @@ -50,12 +50,12 @@ variantType convertToVariant(const QList &val) } template <> -QVariantMap convertToVariant(const QStringMap &val) +QVariantMap convertToVariant(const rdcstrpairs &val) { QVariantMap ret; - for(const QString &k : val.keys()) + for(const rdcstrpair &k : val) { - ret[k] = val[k]; + ret[k.first] = k.second; } return ret; } @@ -67,33 +67,33 @@ origType convertFromVariant(const variantType &val) } template <> -QString convertFromVariant(const QVariant &val) +rdcstr convertFromVariant(const QVariant &val) { return val.toString(); } template -listType convertFromVariant(const QList &val) +listType convertFromVariant(const QVariantList &val) { listType ret; ret.reserve(val.count()); for(const QVariant &s : val) - ret.push_back(convertFromVariant(s)); + ret.push_back(convertFromVariant(s)); return ret; } template <> -QStringMap convertFromVariant(const QVariantMap &val) +rdcstrpairs convertFromVariant(const QVariantMap &val) { - QStringMap ret; + rdcstrpairs ret; for(const QString &k : val.keys()) { - ret[k] = val[k].toString(); + ret.push_back(make_rdcpair(k, val[k].toString())); } return ret; } -bool PersistantConfig::Deserialize(const QString &filename) +bool PersistantConfig::Deserialize(const rdcstr &filename) { QFile f(filename); @@ -117,12 +117,12 @@ bool PersistantConfig::Deserialize(const QString &filename) return true; } - qInfo() << "Couldn't load layout from " << filename << " " << f.errorString(); + qInfo() << "Couldn't load layout from " << QString(filename) << " " << f.errorString(); return false; } -bool PersistantConfig::Serialize(const QString &filename) +bool PersistantConfig::Serialize(const rdcstr &filename) { if(!filename.isEmpty()) m_Filename = filename; @@ -133,7 +133,7 @@ bool PersistantConfig::Serialize(const QString &filename) if(f.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) return SaveToJSON(values, f, JSON_ID, JSON_VER); - qWarning() << "Couldn't write to " << m_Filename << " " << f.errorString(); + qWarning() << "Couldn't write to " << QString(m_Filename) << " " << f.errorString(); return false; } @@ -181,7 +181,7 @@ void PersistantConfig::applyValues(const QVariantMap &values) void PersistantConfig::AddAndroidHosts() { - QMap oldHosts; + QMap oldHosts; for(int i = RemoteHosts.count() - 1; i >= 0; i--) { if(RemoteHosts[i]->IsHostADB()) @@ -192,12 +192,12 @@ void PersistantConfig::AddAndroidHosts() } QString adbExePath = - QFile::exists(Android_AdbExecutablePath) ? Android_AdbExecutablePath : QString(); + QFile::exists(Android_AdbExecutablePath) ? QString(Android_AdbExecutablePath) : QString(); // Set the config setting as it will be reused when we start the remoteserver etc. - SetConfigSetting(lit("adbExePath"), adbExePath); + SetConfigSetting("adbExePath", adbExePath); - SetConfigSetting(lit("MaxConnectTimeout"), QString::number(Android_MaxConnectTimeout)); + SetConfigSetting("MaxConnectTimeout", QString::number(Android_MaxConnectTimeout)); SetConfigSetting(lit("Android_AutoPushLayerToApp"), Android_AutoPushLayerToApp ? lit("1") : lit("0")); @@ -224,7 +224,7 @@ void PersistantConfig::AddAndroidHosts() } // delete any leftovers - QMapIterator i(oldHosts); + QMapIterator i(oldHosts); while(i.hasNext()) { i.next(); @@ -236,15 +236,15 @@ bool PersistantConfig::SetStyle() { for(int i = 0; i < StyleData::numAvailable; i++) { - if(UIStyle == StyleData::availStyles[i].styleID) + if(UIStyle == rdcstr(StyleData::availStyles[i].styleID)) { QApplication::setStyle(StyleData::availStyles[i].creator()); return true; } } - if(UIStyle != QString()) - qCritical() << "Unrecognised UI style" << UIStyle; + if(UIStyle != "") + qCritical() << "Unrecognised UI style" << QString(UIStyle); return false; } @@ -255,15 +255,15 @@ PersistantConfig::~PersistantConfig() delete h; } -bool PersistantConfig::Load(const QString &filename) +bool PersistantConfig::Load(const rdcstr &filename) { bool ret = Deserialize(filename); // perform some sanitisation to make sure config is always in sensible state - for(const QString &key : ConfigSettings.keys()) + for(const rdcstrpair &key : ConfigSettings) { // redundantly set each setting so it is flushed to the core dll - SetConfigSetting(key, ConfigSettings[key]); + SetConfigSetting(key.first, key.second); } RENDERDOC_SetConfigSetting("Disassembly_FriendlyNaming", ShaderViewer_FriendlyNaming ? "1" : "0"); @@ -275,15 +275,15 @@ bool PersistantConfig::Load(const QString &filename) { RemoteHosts.push_back(new RemoteHost(host)); - if(host.Hostname == lit("localhost")) + if(host.IsLocalhost()) foundLocalhost = true; } if(!foundLocalhost) { RemoteHost *host = new RemoteHost(); - host->Hostname = lit("localhost"); - RemoteHosts.insert(RemoteHosts.begin(), host); + host->Hostname = "localhost"; + RemoteHosts.insert(0, host); } return ret; @@ -314,7 +314,7 @@ void PersistantConfig::SetupFormatting() Formatter::setParams(*this); } -void AddRecentFile(QList &recentList, const QString &file, int maxItems) +void AddRecentFile(rdcarray &recentList, const rdcstr &file, int maxItems) { QDir dir(file); QString path = dir.canonicalPath(); @@ -323,7 +323,7 @@ void AddRecentFile(QList &recentList, const QString &file, int maxItems { recentList.push_back(path); if(recentList.count() >= maxItems) - recentList.removeAt(0); + recentList.erase(0); } else { @@ -332,21 +332,34 @@ void AddRecentFile(QList &recentList, const QString &file, int maxItems } } -void PersistantConfig::SetConfigSetting(const QString &name, const QString &value) +void PersistantConfig::SetConfigSetting(const rdcstr &name, const rdcstr &value) { if(name.isEmpty()) return; - ConfigSettings[name] = value; - RENDERDOC_SetConfigSetting(name.toUtf8().data(), value.toUtf8().data()); + bool found = false; + for(rdcstrpair &kv : ConfigSettings) + { + if(kv.first == name) + { + kv.second = value; + found = true; + break; + } + } + + if(!found) + ConfigSettings.push_back(make_rdcpair(name, value)); + RENDERDOC_SetConfigSetting(name.data(), value.data()); } -QString PersistantConfig::GetConfigSetting(const QString &name) +rdcstr PersistantConfig::GetConfigSetting(const rdcstr &name) { - if(ConfigSettings.contains(name)) - return ConfigSettings[name]; + for(const rdcstrpair &kv : ConfigSettings) + if(kv.first == name) + return kv.second; - return QString(); + return ""; } SPIRVDisassembler::SPIRVDisassembler(const QVariant &var) diff --git a/qrenderdoc/Code/Interface/PersistantConfig.h b/qrenderdoc/Code/Interface/PersistantConfig.h index c5b07a9e3..bbc0dc5e5 100644 --- a/qrenderdoc/Code/Interface/PersistantConfig.h +++ b/qrenderdoc/Code/Interface/PersistantConfig.h @@ -28,8 +28,6 @@ #include "QRDInterface.h" #include "RemoteHost.h" -typedef QMap QStringMap; - DOCUMENT("Describes an external program that can be used to disassemble SPIR-V."); struct SPIRVDisassembler { @@ -37,11 +35,11 @@ struct SPIRVDisassembler VARIANT_CAST(SPIRVDisassembler); DOCUMENT("The human-readable name of the program."); - QString name; + rdcstr name; DOCUMENT("The path to the executable to run for this program."); - QString executable; + rdcstr executable; DOCUMENT("The command line argmuents to pass to the program."); - QString args; + rdcstr args; }; DECLARE_REFLECTION_STRUCT(SPIRVDisassembler); @@ -59,21 +57,21 @@ DECLARE_REFLECTION_STRUCT(SPIRVDisassembler); // Note that only public properties should be documented. #define CONFIG_SETTINGS() \ \ - CONFIG_SETTING_VAL(public, QString, QString, UIStyle, QString()) \ + CONFIG_SETTING_VAL(public, QString, rdcstr, UIStyle, "") \ \ - CONFIG_SETTING_VAL(public, QString, QString, LastCaptureFilePath, QString()) \ + CONFIG_SETTING_VAL(public, QString, rdcstr, LastCaptureFilePath, "") \ \ - CONFIG_SETTING(public, QVariantList, QList, RecentCaptureFiles) \ + CONFIG_SETTING(public, QVariantList, rdcarray, RecentCaptureFiles) \ \ - CONFIG_SETTING_VAL(public, QString, QString, LastCapturePath, QString()) \ + CONFIG_SETTING_VAL(public, QString, rdcstr, LastCapturePath, "") \ \ - CONFIG_SETTING_VAL(public, QString, QString, LastCaptureExe, QString()) \ + CONFIG_SETTING_VAL(public, QString, rdcstr, LastCaptureExe, "") \ \ - CONFIG_SETTING(public, QVariantList, QList, RecentCaptureSettings) \ + CONFIG_SETTING(public, QVariantList, rdcarray, RecentCaptureSettings) \ \ - CONFIG_SETTING_VAL(public, QString, QString, TemporaryCaptureDirectory, QString()) \ + CONFIG_SETTING_VAL(public, QString, rdcstr, TemporaryCaptureDirectory, "") \ \ - CONFIG_SETTING_VAL(public, QString, QString, DefaultCaptureSaveDirectory, QString()) \ + CONFIG_SETTING_VAL(public, QString, rdcstr, DefaultCaptureSaveDirectory, "") \ \ CONFIG_SETTING_VAL(public, bool, bool, TextureViewer_ResetRange, false) \ \ @@ -109,7 +107,7 @@ DECLARE_REFLECTION_STRUCT(SPIRVDisassembler); \ CONFIG_SETTING_VAL(public, bool, bool, Font_PreferMonospaced, false) \ \ - CONFIG_SETTING_VAL(public, QString, QString, Android_AdbExecutablePath, QString()) \ + CONFIG_SETTING_VAL(public, QString, rdcstr, Android_AdbExecutablePath, "") \ \ CONFIG_SETTING_VAL(public, int, int, Android_MaxConnectTimeout, 30) \ \ @@ -119,7 +117,7 @@ DECLARE_REFLECTION_STRUCT(SPIRVDisassembler); \ CONFIG_SETTING_VAL(public, bool, bool, CheckUpdate_UpdateAvailable, false) \ \ - CONFIG_SETTING_VAL(public, QString, QString, CheckUpdate_UpdateResponse, QString()) \ + CONFIG_SETTING_VAL(public, QString, rdcstr, CheckUpdate_UpdateResponse, "") \ \ CONFIG_SETTING_VAL(public, QDateTime, QDateTime, CheckUpdate_LastUpdate, \ QDateTime(QDate(2012, 06, 27), QTime(0, 0, 0))) \ @@ -131,15 +129,15 @@ DECLARE_REFLECTION_STRUCT(SPIRVDisassembler); \ CONFIG_SETTING_VAL(public, bool, bool, AllowGlobalHook, false) \ \ - CONFIG_SETTING(public, QVariantList, QList, SPIRVDisassemblers) \ + CONFIG_SETTING(public, QVariantList, rdcarray, SPIRVDisassemblers) \ \ CONFIG_SETTING_VAL(public, bool, bool, Analytics_TotalOptOut, false) \ \ CONFIG_SETTING_VAL(public, bool, bool, Analytics_ManualCheck, false) \ \ - CONFIG_SETTING(private, QVariantMap, QStringMap, ConfigSettings) \ + CONFIG_SETTING(private, QVariantMap, rdcstrpairs, ConfigSettings) \ \ - CONFIG_SETTING(private, QVariantList, QList, RemoteHostList) + CONFIG_SETTING(private, QVariantList, rdcarray, RemoteHostList) DOCUMENT(R"(The unit that GPU durations are displayed in. @@ -173,19 +171,19 @@ DOCUMENT(R"(Gets the suffix for a time unit. :return: The one or two character suffix. :rtype: ``str`` )"); -inline QString UnitSuffix(TimeUnit unit) +inline rdcstr UnitSuffix(TimeUnit unit) { if(unit == TimeUnit::Seconds) - return lit("s"); + return "s"; else if(unit == TimeUnit::Milliseconds) - return lit("ms"); + return "ms"; else if(unit == TimeUnit::Microseconds) // without a BOM in the file, this will break using lit() in MSVC - return QString::fromUtf8("µs"); + return "µs"; else if(unit == TimeUnit::Nanoseconds) - return lit("ns"); + return "ns"; - return lit("s"); + return "s"; } DOCUMENT(R"(Checks if a given file is in a list. If it is, then it's shuffled to the end. If it's @@ -198,7 +196,7 @@ As the name suggests, this is used for tracking a 'recent file' list. :param str file: The file to add to the list. :param int maxItems: The maximum allowed length of the list. )"); -void AddRecentFile(QList &recentList, const QString &file, int maxItems); +void AddRecentFile(rdcarray &recentList, const rdcstr &file, int maxItems); DOCUMENT2(R"(A persistant config file that is automatically loaded and saved, which contains any settings and information that needs to be preserved from one run to the next. @@ -423,10 +421,6 @@ For more information about some of these settings that are user-facing see A list of :class:`SPIRVDisassembler` detailing the potential disassembler programs. The first one in the list is the default. -.. data:: RemoteHosts - - A ``list`` of :class:`RemoteHost` handles to the currently configured remote hosts. - .. data:: Analytics_TotalOptOut ``True`` if the user has selected to completely opt-out from and disable all analytics collection @@ -445,12 +439,40 @@ For more information about some of these settings that are user-facing see class PersistantConfig { public: +// don't allow SWIG direct access to the RemoteHosts since they're an array of references and our +// bindings can't handle that properly +#if !defined(SWIG) // Runtime list of dynamically allocated hosts. // Saved to/from private RemoteHostList in CONFIG_SETTINGS() // This is documented above in the docstring, similar to the values in CONFIG_SETTINGS() DOCUMENT(""); - QList RemoteHosts; + rdcarray RemoteHosts; +#endif + DOCUMENT(R"(Returns the number of remote hosts currently registered. + +:return: The number of remote hosts. +:rtype: ``int`` +)"); + int RemoteHostCount() { return RemoteHosts.count(); } + DOCUMENT(R"(Returns a given remote host at an index. + +:param int index: The index of the remote host to retrieve +:return: The remote host specified, or ``None`` if an invalid index was passed +:rtype: ``RemoteHost`` +)"); + RemoteHost *GetRemoteHost(int index) + { + if(index < 0 || index >= RemoteHostCount()) + return NULL; + return RemoteHosts[index]; + } + + DOCUMENT(R"(Adds a new remote host. + +:param RemoteHost host: The remote host to add. +R)"); + void AddRemoteHost(RemoteHost host) { RemoteHosts.push_back(new RemoteHost(host)); } DOCUMENT("If configured, queries ``adb`` to add android hosts to :data:`RemoteHosts`."); void AddAndroidHosts(); @@ -461,12 +483,13 @@ public: ~PersistantConfig(); DOCUMENT(R"(Loads the config from a given filename. This happens automatically on startup, so it's -not recommended thattyou call this function manually. +not recommended that you call this function manually. +:param str filename: The filename to load from :return: A boolean status if the load was successful. :rtype: ``bool`` )"); - bool Load(const QString &filename); + bool Load(const rdcstr &filename); DOCUMENT(R"(Saves the config to disk. This can happen if you want to be sure a setting has been propagated and will not be forgotten in the case of crash or otherwise unexpected exit. @@ -494,14 +517,14 @@ storing custom settings to be persisted without needing to modify code. :param str name: The name of the setting. Any existing setting will be overwritten. :param str value: The contents of the setting. )"); - void SetConfigSetting(const QString &name, const QString &value); + void SetConfigSetting(const rdcstr &name, const rdcstr &value); DOCUMENT(R"(Retrieves an arbitrary dynamic setting. See :meth:`SetConfigSetting`. :param str name: The name of the setting. :return: The value of the setting, or the empty string if the setting did not exist. :rtype: ``str`` )"); - QString GetConfigSetting(const QString &name); + rdcstr GetConfigSetting(const rdcstr &name); DOCUMENT(R"(Sets the UI style to the value in :data:`UIStyle`. @@ -516,10 +539,10 @@ sure the new style is applied, the application should be restarted. bool SetStyle(); private: - bool Deserialize(const QString &filename); - bool Serialize(const QString &filename); + bool Deserialize(const rdcstr &filename); + bool Serialize(const rdcstr &filename); QVariantMap storeValues() const; void applyValues(const QVariantMap &values); - QString m_Filename; + rdcstr m_Filename; }; diff --git a/qrenderdoc/Code/Interface/QRDInterface.cpp b/qrenderdoc/Code/Interface/QRDInterface.cpp index e8563863e..0b6391159 100644 --- a/qrenderdoc/Code/Interface/QRDInterface.cpp +++ b/qrenderdoc/Code/Interface/QRDInterface.cpp @@ -88,7 +88,7 @@ CaptureSettings::operator QVariant() const ret[lit("CmdLine")] = CmdLine; QVariantList env; - for(int i = 0; i < Environment.size(); i++) + for(int i = 0; i < Environment.count(); i++) env.push_back(EnvModToVariant(Environment[i])); ret[lit("Environment")] = env; @@ -144,7 +144,7 @@ CaptureSettings::CaptureSettings(const QVariant &v) Options.DebugOutputMute = opts[lit("DebugOutputMute")].toBool(); } -QString configFilePath(const QString &filename) +rdcstr configFilePath(const rdcstr &filename) { QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); diff --git a/qrenderdoc/Code/Interface/QRDInterface.h b/qrenderdoc/Code/Interface/QRDInterface.h index ab085d6e8..668743f42 100644 --- a/qrenderdoc/Code/Interface/QRDInterface.h +++ b/qrenderdoc/Code/Interface/QRDInterface.h @@ -4,13 +4,7 @@ // types in the RenderDoc core interface are already wrapped, and Qt types must either be manually // converted directly to python, or interfaced with PySide, otherwise we get into the situation // where pyside and SWIG have independent incompatible wrappers of Qt types -#include #include -#include -#include -#include -#include -#include #include @@ -54,10 +48,17 @@ class QWidget; classname(const QVariant &var); \ operator QVariant() const; +// we also add some headers here that are only needed for Qt helpers in the replay interface, which +// is not exposed to swig +#define RENDERDOC_QT_COMPAT +#include +#include +#include +#include + #endif // we depend on the internal RenderDoc API, but the bindings for that are imported entirely -#define RENDERDOC_QT_COMPAT #include "renderdoc_replay.h" #include "Analytics.h" @@ -83,15 +84,15 @@ struct CaptureSettings DOCUMENT("``True`` if this capture settings object should be immediately executed upon load."); bool AutoStart; DOCUMENT("The path to the executable to run."); - QString Executable; + rdcstr Executable; DOCUMENT("The path to the working directory to run in, or blank for the executable's directory."); - QString WorkingDir; + rdcstr WorkingDir; DOCUMENT("The command line to pass when running :data:`Exectuable`."); - QString CmdLine; + rdcstr CmdLine; DOCUMENT( "A ``list`` of :class:`~renderdoc.EnvironmentModification` with environment changes to " "apply."); - QList Environment; + rdcarray Environment; }; DECLARE_REFLECTION_STRUCT(CaptureSettings); @@ -127,7 +128,7 @@ will be invoked, if it exists. for a global shortcut. Note that if an existing global shortcut exists the new one will not be registered. )"); - virtual void RegisterShortcut(const QString &shortcut, QWidget *widget, + virtual void RegisterShortcut(const rdcstr &shortcut, QWidget *widget, ShortcutCallback callback) = 0; DOCUMENT(R"(Unregister a callback for a particular key shortcut, made in a previous call to @@ -141,7 +142,7 @@ See the documentation for :meth:`RegisterShortcut` for what these shortcuts are :param QWidget widget: A handle to the widget used as the context for the shortcut, or ``None`` if referring to a global shortcut. )"); - virtual void UnregisterShortcut(const QString &shortcut, QWidget *widget) = 0; + virtual void UnregisterShortcut(const rdcstr &shortcut, QWidget *widget) = 0; protected: IMainWindow() = default; @@ -260,7 +261,7 @@ struct IBufferViewer :param str format: Optionally a HLSL/GLSL style formatting string. )"); virtual void ViewBuffer(uint64_t byteOffset, uint64_t byteSize, ResourceId id, - const QString &format = QString()) = 0; + const rdcstr &format = "") = 0; DOCUMENT(R"(In a raw buffer viewer, load the contents from a particular texture resource. :param int arrayIdx: The array slice to load from. @@ -269,7 +270,7 @@ struct IBufferViewer :param str format: Optionally a HLSL/GLSL style formatting string. )"); virtual void ViewTexture(uint32_t arrayIdx, uint32_t mip, ResourceId id, - const QString &format = QString()) = 0; + const rdcstr &format = "") = 0; protected: IBufferViewer() = default; @@ -332,25 +333,25 @@ struct ICaptureDialog :param str filename: The filename to execute. )"); - virtual void SetExecutableFilename(const QString &filename) = 0; + virtual void SetExecutableFilename(const rdcstr &filename) = 0; DOCUMENT(R"(Sets the working directory for capture. :param str dir: The directory to use. )"); - virtual void SetWorkingDirectory(const QString &dir) = 0; + virtual void SetWorkingDirectory(const rdcstr &dir) = 0; DOCUMENT(R"(Sets the command line string to use when launching an executable. :param str cmd: The command line to use. )"); - virtual void SetCommandLine(const QString &cmd) = 0; + virtual void SetCommandLine(const rdcstr &cmd) = 0; DOCUMENT(R"(Sets the list of environment modifications to apply when launching. :param list modifications: The list of :class:`~renderdoc.EnvironmentModification` to apply. )"); - virtual void SetEnvironmentModifications(const QList &modifications) = 0; + virtual void SetEnvironmentModifications(const rdcarray &modifications) = 0; DOCUMENT(R"(Configures the window based on a bulk structure of settings. @@ -372,13 +373,13 @@ struct ICaptureDialog :param str filename: The filename to load the settings from. )"); - virtual void LoadSettings(QString filename) = 0; + virtual void LoadSettings(const rdcstr &filename) = 0; DOCUMENT(R"(Saves the current settings to a file. See :meth:`Settings`. :param str filename: The filename to save the settings to. )"); - virtual void SaveSettings(QString filename) = 0; + virtual void SaveSettings(const rdcstr &filename) = 0; DOCUMENT("Update the current state of the global hook, e.g. if it has been enabled."); virtual void UpdateGlobalHook() = 0; @@ -455,7 +456,7 @@ struct ITimelineBar :param ~renderdoc.ResourceId id: The ID of the resource that is being modified. :param list history: A list of :class:`~renderdoc.PixelModification` events to display. )"); - virtual void HighlightHistory(ResourceId id, const QList &history) = 0; + virtual void HighlightHistory(ResourceId id, const rdcarray &history) = 0; protected: ITimelineBar() = default; @@ -505,7 +506,8 @@ DOCUMENT(R"(A shader window used for viewing, editing, or debugging. :param CaptureContext context: The current capture context. :param ShaderViewer viewer: The open shader viewer. - :param dict files: A dictionary with ``str`` filename keys and ``str`` file contents values. + :param list files: A ``list`` with 2-tuples of ``str``, the first element being the filename and + the second element being the file contents. .. function:: CloseCallback(context) @@ -517,7 +519,7 @@ DOCUMENT(R"(A shader window used for viewing, editing, or debugging. )"); struct IShaderViewer { - typedef std::function SaveCallback; + typedef std::function SaveCallback; typedef std::function CloseCallback; DOCUMENT( @@ -549,7 +551,7 @@ struct IShaderViewer :param str errors: The string of errors or warnings to display. )"); - virtual void ShowErrors(const QString &errors) = 0; + virtual void ShowErrors(const rdcstr &errors) = 0; protected: IShaderViewer() = default; @@ -634,6 +636,7 @@ protected: }; DECLARE_REFLECTION_STRUCT(ICaptureViewer); +DECLARE_REFLECTION_STRUCT(ICaptureViewer *); DOCUMENT(R"(A manager for accessing the underlying replay information that isn't already abstracted in UI side structures. This manager controls and serialises access to the underlying @@ -663,7 +666,7 @@ struct IReplayManager :param str capturefile: The path to the file. :param bool local: ``True`` if the file is on the local machine. )"); - virtual void DeleteCapture(const QString &capturefile, bool local) = 0; + virtual void DeleteCapture(const rdcstr &capturefile, bool local) = 0; DOCUMENT(R"(Connect to a remote server. @@ -715,16 +718,17 @@ This happens either locally, or on the remote server, depending on whether a con wrong. :rtype: ``int`` )"); - virtual uint32_t ExecuteAndInject(const QString &exe, const QString &workingDir, - const QString &cmdLine, const QList &env, - const QString &capturefile, CaptureOptions opts) = 0; + virtual uint32_t ExecuteAndInject(const rdcstr &exe, const rdcstr &workingDir, + const rdcstr &cmdLine, + const rdcarray &env, + const rdcstr &capturefile, CaptureOptions opts) = 0; DOCUMENT(R"(Retrieve a list of drivers that the current remote server supports. :return: The list of supported replay drivers. :rtype: ``list`` of ``str``. )"); - virtual QStringList GetRemoteSupport() = 0; + virtual rdcarray GetRemoteSupport() = 0; DOCUMENT(R"(Query the remote host for its home directory. @@ -747,7 +751,7 @@ blocking fashion on the current thread. the callback. Otherwise if ``False`` then :meth:`AsyncInvoke` will be used. :param DirectoryBrowseMethod method: The function to callback on the replay thread. )"); - virtual void ListFolder(QString path, bool synchronous, DirectoryBrowseCallback cb) = 0; + virtual void ListFolder(const rdcstr &path, bool synchronous, DirectoryBrowseCallback cb) = 0; DOCUMENT(R"(Copy a capture from the local machine to the remote host. @@ -756,7 +760,7 @@ blocking fashion on the current thread. :param QWidget window: A handle to the window to use when showing a progress bar. :rtype: ``str`` )"); - virtual QString CopyCaptureToRemote(const QString &localpath, QWidget *window) = 0; + virtual rdcstr CopyCaptureToRemote(const rdcstr &localpath, QWidget *window) = 0; DOCUMENT(R"(Copy a capture from the remote host to the local machine. @@ -764,7 +768,7 @@ blocking fashion on the current thread. :param str localpath: The path on the local machine to copy to. :param QWidget window: A handle to the window to use when showing a progress bar. )"); - virtual void CopyCaptureFromRemote(const QString &remotepath, const QString &localpath, + virtual void CopyCaptureFromRemote(const rdcstr &remotepath, const rdcstr &localpath, QWidget *window) = 0; DOCUMENT(R"(Make a tagged non-blocking invoke call onto the replay thread. @@ -780,7 +784,7 @@ comes in, we remove any other requests in the queue before it that have the same :param str tag: The tag to identify this callback. :param InvokeCallback method: The function to callback on the replay thread. )"); - virtual void AsyncInvoke(const QString &tag, InvokeCallback method) = 0; + virtual void AsyncInvoke(const rdcstr &tag, InvokeCallback method) = 0; DOCUMENT(R"(Make a non-blocking invoke call onto the replay thread. @@ -946,7 +950,7 @@ struct EventBookmark uint32_t EID = 0; DOCUMENT("The text associated with this bookmark - could be empty"); - QString text; + rdcstr text; DOCUMENT(""); EventBookmark() = default; @@ -956,6 +960,8 @@ struct EventBookmark bool operator<(const EventBookmark &o) const { return EID < o.EID; } }; +DECLARE_REFLECTION_STRUCT(EventBookmark); + DOCUMENT("The capture context that the python script is running in.") struct ICaptureContext { @@ -966,7 +972,7 @@ data. :return: The absolute path. :rtype: ``str`` )"); - virtual QString TempCaptureFilename(QString appname) = 0; + virtual rdcstr TempCaptureFilename(const rdcstr &appname) = 0; DOCUMENT(R"(Open a capture file for replay. @@ -976,7 +982,7 @@ data. either save or delete on close. :param bool local: ``True`` if ``captureFile`` refers to a file on the local machine. )"); - virtual void LoadCapture(const QString &captureFile, const QString &origFilename, bool temporary, + virtual void LoadCapture(const rdcstr &captureFile, const rdcstr &origFilename, bool temporary, bool local) = 0; DOCUMENT(R"(Saves the current capture file to a given path. @@ -991,7 +997,7 @@ time. :return: ``True`` if the save operation was successful. :rtype: ``bool`` )"); - virtual bool SaveCaptureTo(const QString &captureFile) = 0; + virtual bool SaveCaptureTo(const rdcstr &captureFile) = 0; DOCUMENT("Recompress the current capture as much as possible."); virtual void RecompressCapture() = 0; @@ -1010,7 +1016,7 @@ time. :param bool force: Optional parameter, if ``True`` then the replay will 'move' even if it is moving to the same :data:`EID ` as it's currently on. )"); - virtual void SetEventID(const QVector &exclude, uint32_t selectedEventID, + virtual void SetEventID(const rdcarray &exclude, uint32_t selectedEventID, uint32_t eventID, bool force = false) = 0; DOCUMENT(R"(Replay the capture to the current event again, to pick up any changes that might have been made. @@ -1075,7 +1081,7 @@ temporary and treated like any other capture. :return: The filename of the current capture. :rtype: ``str`` )"); - virtual QString GetCaptureFilename() = 0; + virtual rdcstr GetCaptureFilename() = 0; DOCUMENT(R"(Get a bitmask indicating which modifications (if any) have been made to the capture in the UI which aren't reflected in the capture file on disk. @@ -1179,7 +1185,7 @@ the resource type. :return: The current name of the resource. :rtype: str )"); - virtual QString GetResourceName(ResourceId id) = 0; + virtual rdcstr GetResourceName(ResourceId id) = 0; DOCUMENT(R"(Determines whether the name for the given resource has been customised at all, either during capture time or with :meth:`SetResourceCustomName`. @@ -1216,7 +1222,7 @@ name fetched from the capture. :param ~renderdoc.ResourceId id: The ID of the resource to name. :param str name: The name to provide, or an empty string to remove any previous custom name. )"); - virtual void SetResourceCustomName(ResourceId id, const QString &name) = 0; + virtual void SetResourceCustomName(ResourceId id, const rdcstr &name) = 0; DOCUMENT(R"(Returns an index that can be used to cache the results of resource naming. @@ -1306,7 +1312,7 @@ as well as messages generated during replay and analysis. :return: The debug messages generated to date. :rtype: ``list`` of :class:`~renderdoc.DebugMessage` )"); - virtual const QVector &DebugMessages() = 0; + virtual const rdcarray &DebugMessages() = 0; DOCUMENT(R"(Retrieve how many messages in :meth:`DebugMessages` are currently unread. @@ -1335,7 +1341,7 @@ Examples of fields are: :return: The contents, or an empty string if the field doesn't exist. :rtype: str )"); - virtual QString GetNotes(const QString &key) = 0; + virtual rdcstr GetNotes(const rdcstr &key) = 0; DOCUMENT(R"(Set the contents for a given notes field. @@ -1344,7 +1350,7 @@ See :meth:`GetNotes` for a list of possible common field keys. :param str key: The name of the notes field to set. :param str contents: The new contents to assign to that field. )"); - virtual void SetNotes(const QString &key, const QString &contents) = 0; + virtual void SetNotes(const rdcstr &key, const rdcstr &contents) = 0; DOCUMENT(R"(Get the current list of bookmarks in the capture. Each bookmark is associated with an EID and has some text attached. There will only be at most one bookmark for any given EID. @@ -1355,7 +1361,7 @@ it is removed, the indices do not shift as new bookmarks are added or removed. :return: The currently set bookmarks. :rtype: ``list`` of :class:`BookMark` )"); - virtual QList GetBookmarks() = 0; + virtual rdcarray GetBookmarks() = 0; DOCUMENT(R"(Set or update a bookmark. @@ -1599,8 +1605,8 @@ If no bookmark exists, this function will do nothing. :param bool customShader: ``True`` if the shader being edited is a custom display shader. :param str entryPoint: The entry point to be used when compiling the edited shader. -:param dict files: The files stored in a ``dict`` with ``str`` keys as filenames and ``str`` values - with the file contents. +:param list files: The files stored in a ``list`` with 2-tuples of ``str``. The first element being + the filename and the second being the file contents. :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 @@ -1608,8 +1614,9 @@ If no bookmark exists, this function will do nothing. :return: The new :class:`ShaderViewer` window opened but not shown for editing. :rtype: ShaderViewer )"); - virtual IShaderViewer *EditShader(bool customShader, const QString &entryPoint, - const QStringMap &files, IShaderViewer::SaveCallback saveCallback, + virtual IShaderViewer *EditShader(bool customShader, const rdcstr &entryPoint, + const rdcstrpairs &files, + IShaderViewer::SaveCallback saveCallback, IShaderViewer::CloseCallback closeCallback) = 0; DOCUMENT(R"(Show a new :class:`ShaderViewer` window, showing a read-only view of a debug trace @@ -1627,7 +1634,7 @@ through the execution of a given shader. )"); virtual IShaderViewer *DebugShader(const ShaderBindpointMapping *bind, const ShaderReflection *shader, ResourceId pipeline, - ShaderDebugTrace *trace, const QString &debugContext) = 0; + ShaderDebugTrace *trace, const rdcstr &debugContext) = 0; DOCUMENT(R"(Show a new :class:`ShaderViewer` window, showing a read-only view of a given shader. @@ -1649,7 +1656,7 @@ through the execution of a given shader. :rtype: BufferViewer )"); virtual IBufferViewer *ViewBuffer(uint64_t byteOffset, uint64_t byteSize, ResourceId id, - const QString &format = QString()) = 0; + const rdcstr &format = "") = 0; DOCUMENT(R"(Show a new :class:`BufferViewer` window, showing a read-only view of a texture's raw bytes. @@ -1662,7 +1669,7 @@ bytes. :rtype: BufferViewer )"); virtual IBufferViewer *ViewTextureAsBuffer(uint32_t arrayIdx, uint32_t mip, ResourceId id, - const QString &format = QString()) = 0; + const rdcstr &format = "") = 0; DOCUMENT(R"(Show a new :class:`ConstantBufferPreviewer` window, showing a read-only view of a the variables in a constant buffer with their values. @@ -1701,7 +1708,7 @@ by user code. not available. :rtype: ``QWidget`` )"); - virtual QWidget *CreateBuiltinWindow(const QString &objectName) = 0; + virtual QWidget *CreateBuiltinWindow(const rdcstr &objectName) = 0; DOCUMENT(R"(Marks a built-in window as closed. @@ -1801,7 +1808,7 @@ data. :return: The absolute path. :rtype: ``str`` )"); -QString configFilePath(const QString &filename); +rdcstr configFilePath(const rdcstr &filename); // simple helper for the common case of 'we just need to run this on the replay thread' #define INVOKE_MEMFN(function) \ diff --git a/qrenderdoc/Code/Interface/RemoteHost.cpp b/qrenderdoc/Code/Interface/RemoteHost.cpp index 5082333c8..4cea8ef1a 100644 --- a/qrenderdoc/Code/Interface/RemoteHost.cpp +++ b/qrenderdoc/Code/Interface/RemoteHost.cpp @@ -57,7 +57,7 @@ RemoteHost::operator QVariant() const void RemoteHost::CheckStatus() { // special case - this is the local context - if(Hostname == lit("localhost")) + if(Hostname == "localhost") { ServerRunning = false; VersionMismatch = Busy = false; @@ -65,7 +65,7 @@ void RemoteHost::CheckStatus() } IRemoteServer *rend = NULL; - ReplayStatus status = RENDERDOC_CreateRemoteServerConnection(Hostname.toUtf8().data(), 0, &rend); + ReplayStatus status = RENDERDOC_CreateRemoteServerConnection(Hostname.c_str(), 0, &rend); if(status == ReplayStatus::Succeeded) { @@ -108,7 +108,7 @@ void RemoteHost::Launch() if(IsHostADB()) { - RENDERDOC_StartAndroidRemoteServer(Hostname.toUtf8().data()); + RENDERDOC_StartAndroidRemoteServer(Hostname.c_str()); QThread::msleep(WAIT_TIME); return; } diff --git a/qrenderdoc/Code/Interface/RemoteHost.h b/qrenderdoc/Code/Interface/RemoteHost.h index de0001379..84cbd4e38 100644 --- a/qrenderdoc/Code/Interface/RemoteHost.h +++ b/qrenderdoc/Code/Interface/RemoteHost.h @@ -53,18 +53,23 @@ public: bool VersionMismatch : 1; DOCUMENT("The hostname of this host."); - QString Hostname; + rdcstr Hostname; DOCUMENT("The friendly name for this host, if available (if empty, the Hostname is used)."); - QString FriendlyName; + rdcstr FriendlyName; DOCUMENT("The command to run locally to try to launch the server remotely."); - QString RunCommand; + rdcstr RunCommand; DOCUMENT(R"( Returns the name to display for this host in the UI, either :data:`FriendlyName` or :data:`Hostname` )"); - const QString &Name() const { return !FriendlyName.isEmpty() ? FriendlyName : Hostname; } + const rdcstr &Name() const { return !FriendlyName.isEmpty() ? FriendlyName : Hostname; } DOCUMENT("Returns ``True`` if this host represents a connected ADB (Android) device."); - bool IsHostADB() const { return Hostname.startsWith(lit("adb:")); } + bool IsHostADB() const + { + return Hostname[0] == 'a' && Hostname[1] == 'd' && Hostname[2] == 'b' && Hostname[3] == ':'; + } + DOCUMENT("Returns ``True`` if this host represents the special localhost device."); + bool IsLocalhost() const { return Hostname == "localhost"; } }; DECLARE_REFLECTION_STRUCT(RemoteHost); \ No newline at end of file diff --git a/qrenderdoc/Code/ReplayManager.cpp b/qrenderdoc/Code/ReplayManager.cpp index 09610a17b..ecb5be947 100644 --- a/qrenderdoc/Code/ReplayManager.cpp +++ b/qrenderdoc/Code/ReplayManager.cpp @@ -59,7 +59,7 @@ void ReplayManager::OpenCapture(const QString &capturefile, float *progress) } } -void ReplayManager::DeleteCapture(const QString &capture, bool local) +void ReplayManager::DeleteCapture(const rdcstr &capture, bool local) { if(IsRunning()) { @@ -78,22 +78,20 @@ void ReplayManager::DeleteCapture(const QString &capture, bool local) if(m_Remote) { QMutexLocker autolock(&m_RemoteLock); - m_Remote->TakeOwnershipCapture(capture.toUtf8().data()); + m_Remote->TakeOwnershipCapture(capture.c_str()); } } } -QStringList ReplayManager::GetRemoteSupport() +rdcarray ReplayManager::GetRemoteSupport() { - QStringList ret; + rdcarray ret; if(m_Remote && !IsRunning()) { QMutexLocker autolock(&m_RemoteLock); - rdcarray supported = m_Remote->RemoteSupportedReplays(); - for(rdcstr &s : supported) - ret << s; + ret = m_Remote->RemoteSupportedReplays(); } return ret; @@ -127,17 +125,15 @@ void ReplayManager::GetHomeFolder(bool synchronous, DirectoryBrowseCallback cb) cb(home.c_str(), rdcarray()); } -void ReplayManager::ListFolder(QString path, bool synchronous, DirectoryBrowseCallback cb) +void ReplayManager::ListFolder(const rdcstr &path, bool synchronous, DirectoryBrowseCallback cb) { if(!m_Remote) return; - QByteArray pathUTF8 = path.toUtf8(); - if(IsRunning() && m_Thread->isCurrentThread()) { - auto lambda = [cb, pathUTF8, this](IReplayController *r) { - cb(pathUTF8.data(), m_Remote->ListFolder(pathUTF8.data())); + auto lambda = [cb, path, this](IReplayController *r) { + cb(path, m_Remote->ListFolder(path.c_str())); }; if(synchronous) @@ -152,27 +148,27 @@ void ReplayManager::ListFolder(QString path, bool synchronous, DirectoryBrowseCa // prevent pings while fetching remote FS data { QMutexLocker autolock(&m_RemoteLock); - contents = m_Remote->ListFolder(pathUTF8.data()); + contents = m_Remote->ListFolder(path.c_str()); } - cb(pathUTF8.data(), contents); + cb(path, contents); return; } -QString ReplayManager::CopyCaptureToRemote(const QString &localpath, QWidget *window) +rdcstr ReplayManager::CopyCaptureToRemote(const rdcstr &localpath, QWidget *window) { if(!m_Remote) - return QString(); + return ""; - QString remotepath; + rdcstr remotepath; bool copied = false; float progress = 0.0f; auto lambda = [this, localpath, &remotepath, &progress, &copied](IReplayController *r) { QMutexLocker autolock(&m_RemoteLock); - remotepath = m_Remote->CopyCaptureToRemote(localpath.toUtf8().data(), &progress); + remotepath = m_Remote->CopyCaptureToRemote(localpath.c_str(), &progress); copied = true; }; @@ -194,7 +190,7 @@ QString ReplayManager::CopyCaptureToRemote(const QString &localpath, QWidget *wi return remotepath; } -void ReplayManager::CopyCaptureFromRemote(const QString &remotepath, const QString &localpath, +void ReplayManager::CopyCaptureFromRemote(const rdcstr &remotepath, const rdcstr &localpath, QWidget *window) { if(!m_Remote) @@ -205,7 +201,7 @@ void ReplayManager::CopyCaptureFromRemote(const QString &remotepath, const QStri auto lambda = [this, localpath, remotepath, &progress, &copied](IReplayController *r) { QMutexLocker autolock(&m_RemoteLock); - m_Remote->CopyCaptureFromRemote(remotepath.toUtf8().data(), localpath.toUtf8().data(), &progress); + m_Remote->CopyCaptureFromRemote(remotepath.c_str(), localpath.c_str(), &progress); copied = true; }; @@ -230,13 +226,15 @@ bool ReplayManager::IsRunning() return m_Thread && m_Thread->isRunning() && m_Running; } -void ReplayManager::AsyncInvoke(const QString &tag, ReplayManager::InvokeCallback m) +void ReplayManager::AsyncInvoke(const rdcstr &tag, ReplayManager::InvokeCallback m) { + QString qtag(tag); + { QMutexLocker autolock(&m_RenderLock); for(int i = 0; i < m_RenderQueue.count();) { - if(m_RenderQueue[i]->tag == tag) + if(m_RenderQueue[i]->tag == qtag) { InvokeHandle *cmd = m_RenderQueue.takeAt(i); if(cmd->selfdelete) @@ -249,7 +247,7 @@ void ReplayManager::AsyncInvoke(const QString &tag, ReplayManager::InvokeCallbac } } - InvokeHandle *cmd = new InvokeHandle(m, tag); + InvokeHandle *cmd = new InvokeHandle(m, qtag); cmd->selfdelete = true; PushInvoke(cmd); @@ -299,8 +297,7 @@ void ReplayManager::CloseThread() ReplayStatus ReplayManager::ConnectToRemoteServer(RemoteHost *host) { - ReplayStatus status = - RENDERDOC_CreateRemoteServerConnection(host->Hostname.toUtf8().data(), 0, &m_Remote); + ReplayStatus status = RENDERDOC_CreateRemoteServerConnection(host->Hostname.c_str(), 0, &m_Remote); if(host->IsHostADB()) { @@ -371,26 +368,22 @@ void ReplayManager::ReopenCaptureFile(const QString &path) m_CaptureFile->OpenFile(path.toUtf8().data(), "rdc"); } -uint32_t ReplayManager::ExecuteAndInject(const QString &exe, const QString &workingDir, - const QString &cmdLine, - const QList &env, - const QString &capturefile, CaptureOptions opts) +uint32_t ReplayManager::ExecuteAndInject(const rdcstr &exe, const rdcstr &workingDir, + const rdcstr &cmdLine, + const rdcarray &env, + const rdcstr &capturefile, CaptureOptions opts) { - rdcarray envList = env.toVector().toStdVector(); - uint32_t ret = 0; if(m_Remote) { QMutexLocker autolock(&m_RemoteLock); - ret = m_Remote->ExecuteAndInject(exe.toUtf8().data(), workingDir.toUtf8().data(), - cmdLine.toUtf8().data(), envList, opts); + ret = m_Remote->ExecuteAndInject(exe.c_str(), workingDir.c_str(), cmdLine.c_str(), env, opts); } else { - ret = RENDERDOC_ExecuteAndInject(exe.toUtf8().data(), workingDir.toUtf8().data(), - cmdLine.toUtf8().data(), envList, capturefile.toUtf8().data(), - opts, false); + ret = RENDERDOC_ExecuteAndInject(exe.c_str(), workingDir.c_str(), cmdLine.c_str(), env, + capturefile.c_str(), opts, false); } return ret; diff --git a/qrenderdoc/Code/ReplayManager.h b/qrenderdoc/Code/ReplayManager.h index 5f35aef43..9bdcbcb1f 100644 --- a/qrenderdoc/Code/ReplayManager.h +++ b/qrenderdoc/Code/ReplayManager.h @@ -48,7 +48,7 @@ public: ~ReplayManager(); void OpenCapture(const QString &capturefile, float *progress); - void DeleteCapture(const QString &capturefile, bool local); + void DeleteCapture(const rdcstr &capturefile, bool local); bool IsRunning(); ReplayStatus GetCreateStatus() { return m_CreateStatus; } @@ -58,7 +58,7 @@ public: // processed. // the manager processes only the request on the top of the queue, so when a new tagged invoke // comes in, we remove any other requests in the queue before it that have the same tag - void AsyncInvoke(const QString &tag, InvokeCallback m); + void AsyncInvoke(const rdcstr &tag, InvokeCallback m); void AsyncInvoke(InvokeCallback m); void BlockInvoke(InvokeCallback m); @@ -85,15 +85,15 @@ public: ICaptureFile *GetCaptureFile() { return m_CaptureFile; } void ReopenCaptureFile(const QString &path); const RemoteHost *CurrentRemote() { return m_RemoteHost; } - uint32_t ExecuteAndInject(const QString &exe, const QString &workingDir, const QString &cmdLine, - const QList &env, const QString &capturefile, + uint32_t ExecuteAndInject(const rdcstr &exe, const rdcstr &workingDir, const rdcstr &cmdLine, + const rdcarray &env, const rdcstr &capturefile, CaptureOptions opts); - QStringList GetRemoteSupport(); + rdcarray GetRemoteSupport(); void GetHomeFolder(bool synchronous, DirectoryBrowseCallback cb); - void ListFolder(QString path, bool synchronous, DirectoryBrowseCallback cb); - QString CopyCaptureToRemote(const QString &localpath, QWidget *window); - void CopyCaptureFromRemote(const QString &remotepath, const QString &localpath, QWidget *window); + void ListFolder(const rdcstr &path, bool synchronous, DirectoryBrowseCallback cb); + rdcstr CopyCaptureToRemote(const rdcstr &localpath, QWidget *window); + void CopyCaptureFromRemote(const rdcstr &remotepath, const rdcstr &localpath, QWidget *window); private: struct InvokeHandle diff --git a/qrenderdoc/Code/pyrenderdoc/container_handling.i b/qrenderdoc/Code/pyrenderdoc/container_handling.i index 218ecfc58..1c23326e0 100644 --- a/qrenderdoc/Code/pyrenderdoc/container_handling.i +++ b/qrenderdoc/Code/pyrenderdoc/container_handling.i @@ -13,6 +13,33 @@ // a typemap that allows us to modify 'self' in place, but convert any inputs by value. %define LIST_MODIFY_IN_PLACE_TYPEMAP(ContainerType) +%typemap(in) const ContainerType & (unsigned char tempmem[32], bool wasSelf = false) { + using array_type = std::remove_pointer::type; + + { + // convert the sequence by value using ConvertFromPy + static_assert(sizeof(tempmem) >= sizeof(array_type), "not enough temp space for $1_basetype"); + + tempalloc($1, tempmem); + + int failIdx = 0; + int res = TypeConversion::ConvertFromPy($input, indirect($1), &failIdx); + + if(!SWIG_IsOK(res)) + { + if(res == SWIG_TypeError) + { + SWIG_exception_fail(SWIG_ArgError(res), "in method '$symname' argument $argnum of type '$1_basetype'"); + } + else + { + snprintf(convert_error, sizeof(convert_error)-1, "in method '$symname' argument $argnum of type '$1_basetype', decoding element %d", failIdx); + SWIG_exception_fail(SWIG_ArgError(res), convert_error); + } + } + } +} + %typemap(in) ContainerType * (unsigned char tempmem[32], bool wasSelf = false) { using array_type = std::remove_pointer::type; @@ -255,6 +282,28 @@ void ARRAY_INSTANTIATION_CHECK_NAME(arrayType)(arrayType *) %enddef +// variation of the above to handle pointer'd inner type +%define TEMPLATE_ARRAY_INSTANTIATE_PTR(arrayType, innerType) + +ARRAY_ADD_SLOTS(arrayType, arrayType##_of_ptr_##innerType) + +// instantiate template +%rename(arrayType##_of_ptr_##innerType) arrayType; +%template(arrayType##_of_ptr_##innerType) arrayType; + +ARRAY_DEFINE_SLOTS(arrayType, arrayType##_of_ptr_##innerType) + +%header %{ + +template<> +void ARRAY_INSTANTIATION_CHECK_NAME(arrayType)(arrayType *) +{ +} + +%} + +%enddef + %define TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(arrayType, nspace, innerType) ARRAY_ADD_SLOTS(arrayType, arrayType##_of_##nspace##_##innerType) diff --git a/qrenderdoc/Code/pyrenderdoc/pyconversion.i b/qrenderdoc/Code/pyrenderdoc/pyconversion.i index 03631881b..791d62fa3 100644 --- a/qrenderdoc/Code/pyrenderdoc/pyconversion.i +++ b/qrenderdoc/Code/pyrenderdoc/pyconversion.i @@ -118,6 +118,7 @@ SIMPLE_TYPEMAPS_VARIANT(SimpleType, SimpleType &) DECLARE_STRINGISE_TYPE(float); DECLARE_STRINGISE_TYPE(double); DECLARE_STRINGISE_TYPE(rdcstr); + DECLARE_STRINGISE_TYPE(rdcstrpair); %} diff --git a/qrenderdoc/Code/pyrenderdoc/qrenderdoc.i b/qrenderdoc/Code/pyrenderdoc/qrenderdoc.i index db114791f..97e444c52 100644 --- a/qrenderdoc/Code/pyrenderdoc/qrenderdoc.i +++ b/qrenderdoc/Code/pyrenderdoc/qrenderdoc.i @@ -76,6 +76,15 @@ TEMPLATE_ARRAY_DECLARE(rdcarray); %include "Code/Interface/PersistantConfig.h" %include "Code/Interface/RemoteHost.h" +TEMPLATE_ARRAY_INSTANTIATE(rdcarray, EventBookmark) +TEMPLATE_ARRAY_INSTANTIATE(rdcarray, SPIRVDisassembler) +TEMPLATE_ARRAY_INSTANTIATE(rdcarray, BoundBuffer) +TEMPLATE_ARRAY_INSTANTIATE(rdcarray, VertexInputAttribute) +TEMPLATE_ARRAY_INSTANTIATE(rdcarray, BoundResource) +TEMPLATE_ARRAY_INSTANTIATE(rdcarray, BoundResourceArray) +TEMPLATE_ARRAY_INSTANTIATE(rdcarray, rdcstrpair) +TEMPLATE_ARRAY_INSTANTIATE_PTR(rdcarray, ICaptureViewer) + // unignore the function from above %rename("%s") IReplayManager::BlockInvoke; diff --git a/qrenderdoc/Code/pyrenderdoc/renderdoc.i b/qrenderdoc/Code/pyrenderdoc/renderdoc.i index 07048dfbb..480847c55 100644 --- a/qrenderdoc/Code/pyrenderdoc/renderdoc.i +++ b/qrenderdoc/Code/pyrenderdoc/renderdoc.i @@ -82,6 +82,7 @@ %ignore rdcarray::end; %ignore rdcarray::front; %ignore rdcarray::back; +%ignore rdcarray::at; %ignore rdcarray::data; %ignore rdcarray::assign; %ignore rdcarray::insert; @@ -98,6 +99,10 @@ %ignore rdcarray::reserve; %ignore rdcarray::swap; %ignore rdcarray::push_back; +%ignore rdcarray::takeAt; +%ignore rdcarray::indexOf; +%ignore rdcarray::contains; +%ignore rdcarray::removeOne; %ignore rdcarray::operator=; %ignore rdcarray::operator[]; %ignore rdcstr::operator=; diff --git a/qrenderdoc/Windows/BufferViewer.cpp b/qrenderdoc/Windows/BufferViewer.cpp index a2e239d52..24d5118fd 100644 --- a/qrenderdoc/Windows/BufferViewer.cpp +++ b/qrenderdoc/Windows/BufferViewer.cpp @@ -1554,13 +1554,13 @@ void BufferViewer::RT_FetchMeshData(IReplayController *r) { const DrawcallDescription *draw = m_Ctx.CurDrawcall(); - QPair ib = m_Ctx.CurPipelineState().GetIBuffer(); + BoundBuffer ib = m_Ctx.CurPipelineState().GetIBuffer(); - QVector vbs = m_Ctx.CurPipelineState().GetVBuffers(); + rdcarray vbs = m_Ctx.CurPipelineState().GetVBuffers(); bytebuf idata; - if(ib.first != ResourceId() && draw && (draw->flags & DrawFlags::UseIBuffer)) - idata = r->GetBufferData(ib.first, ib.second + draw->indexOffset * draw->indexByteWidth, + if(ib.Buffer != ResourceId() && draw && (draw->flags & DrawFlags::UseIBuffer)) + idata = r->GetBufferData(ib.Buffer, ib.ByteOffset + draw->indexOffset * draw->indexByteWidth, draw->numIndices * draw->indexByteWidth); uint32_t *indices = NULL; @@ -1631,7 +1631,7 @@ void BufferViewer::RT_FetchMeshData(IReplayController *r) } int vbIdx = 0; - for(BoundVBuffer vb : vbs) + for(BoundBuffer vb : vbs) { bool used = false; bool pi = false; @@ -2094,7 +2094,7 @@ void BufferViewer::updatePreviewColumns() if(!m_MeshView) return; - QVector vbs = m_Ctx.CurPipelineState().GetVBuffers(); + rdcarray vbs = m_Ctx.CurPipelineState().GetVBuffers(); const DrawcallDescription *draw = m_Ctx.CurDrawcall(); if(draw) @@ -2112,9 +2112,9 @@ void BufferViewer::updatePreviewColumns() m_VSInPosition.topo = draw->topology; m_VSInPosition.idxByteWidth = draw->indexByteWidth; m_VSInPosition.baseVertex = draw->baseVertex; - QPair ib = m_Ctx.CurPipelineState().GetIBuffer(); - m_VSInPosition.idxbuf = ib.first; - m_VSInPosition.idxoffs = ib.second + draw->indexOffset * draw->indexByteWidth; + BoundBuffer ib = m_Ctx.CurPipelineState().GetIBuffer(); + m_VSInPosition.idxbuf = ib.Buffer; + m_VSInPosition.idxoffs = ib.ByteOffset + draw->indexOffset * draw->indexByteWidth; if((draw->flags & DrawFlags::UseIBuffer) && m_VSInPosition.idxByteWidth == 0) m_VSInPosition.idxByteWidth = 4U; @@ -2235,7 +2235,7 @@ void BufferViewer::configureMeshColumns() { const DrawcallDescription *draw = m_Ctx.CurDrawcall(); - QVector vinputs = m_Ctx.CurPipelineState().GetVertexInputs(); + rdcarray vinputs = m_Ctx.CurPipelineState().GetVertexInputs(); m_ModelVSIn->columns.reserve(vinputs.count()); m_ModelVSIn->genericsEnabled.resize(vinputs.count()); @@ -2591,7 +2591,7 @@ void BufferViewer::ScrollToRow(BufferItemModel *model, int row) } void BufferViewer::ViewBuffer(uint64_t byteOffset, uint64_t byteSize, ResourceId id, - const QString &format) + const rdcstr &format) { if(!m_Ctx.IsCaptureLoaded()) return; @@ -2610,7 +2610,7 @@ void BufferViewer::ViewBuffer(uint64_t byteOffset, uint64_t byteSize, ResourceId processFormat(format); } -void BufferViewer::ViewTexture(uint32_t arrayIdx, uint32_t mip, ResourceId id, const QString &format) +void BufferViewer::ViewTexture(uint32_t arrayIdx, uint32_t mip, ResourceId id, const rdcstr &format) { if(!m_Ctx.IsCaptureLoaded()) return; diff --git a/qrenderdoc/Windows/BufferViewer.h b/qrenderdoc/Windows/BufferViewer.h index a2991aac2..2f6939cd4 100644 --- a/qrenderdoc/Windows/BufferViewer.h +++ b/qrenderdoc/Windows/BufferViewer.h @@ -78,9 +78,8 @@ public: ScrollToRow(m_ModelVSIn, row); } void ViewBuffer(uint64_t byteOffset, uint64_t byteSize, ResourceId id, - const QString &format = QString()) override; - void ViewTexture(uint32_t arrayIdx, uint32_t mip, ResourceId id, - const QString &format = QString()) override; + const rdcstr &format = "") override; + void ViewTexture(uint32_t arrayIdx, uint32_t mip, ResourceId id, const rdcstr &format = "") override; // ICaptureViewer void OnCaptureLoaded() override; diff --git a/qrenderdoc/Windows/CommentView.cpp b/qrenderdoc/Windows/CommentView.cpp index 7b3c64df8..e6171bc68 100644 --- a/qrenderdoc/Windows/CommentView.cpp +++ b/qrenderdoc/Windows/CommentView.cpp @@ -77,7 +77,7 @@ void CommentView::OnCaptureClosed() void CommentView::OnCaptureLoaded() { - m_commentsEditor->setText(m_Ctx.GetNotes(lit("comments")).toUtf8().data()); + m_commentsEditor->setText(m_Ctx.GetNotes("comments").c_str()); m_commentsEditor->emptyUndoBuffer(); m_ignoreModifications = false; } @@ -85,7 +85,7 @@ void CommentView::OnCaptureLoaded() void CommentView::OnEventChanged(uint32_t eventID) { QString oldText = QString::fromUtf8(m_commentsEditor->getText(m_commentsEditor->textLength() + 1)); - QString newText = m_Ctx.GetNotes(lit("comments")); + QString newText = m_Ctx.GetNotes("comments"); if(oldText != newText) { diff --git a/qrenderdoc/Windows/Dialogs/CaptureDialog.cpp b/qrenderdoc/Windows/Dialogs/CaptureDialog.cpp index b24456b08..f19ab6b53 100644 --- a/qrenderdoc/Windows/Dialogs/CaptureDialog.cpp +++ b/qrenderdoc/Windows/Dialogs/CaptureDialog.cpp @@ -425,8 +425,8 @@ void CaptureDialog::CheckAndroidSetup(QString &filename) LambdaThread *scan = new LambdaThread([this, filename]() { - QByteArray hostnameBytes = m_Ctx.Replay().CurrentRemote()->Hostname.toUtf8(); - RENDERDOC_CheckAndroidPackage(hostnameBytes.data(), filename.toUtf8().data(), &m_AndroidFlags); + rdcstr host = m_Ctx.Replay().CurrentRemote()->Hostname; + RENDERDOC_CheckAndroidPackage(host.c_str(), filename.toUtf8().data(), &m_AndroidFlags); const bool missingLibrary = bool(m_AndroidFlags & AndroidFlags::MissingLibrary); const bool missingPermissions = bool(m_AndroidFlags & AndroidFlags::MissingPermissions); @@ -534,8 +534,8 @@ void CaptureDialog::androidWarn_mouseClick() // Call into layer push routine, then continue LambdaThread *push = new LambdaThread([this, exe, &pushSucceeded]() { - QByteArray hostnameBytes = m_Ctx.Replay().CurrentRemote()->Hostname.toUtf8(); - if(RENDERDOC_PushLayerToInstalledAndroidApp(hostnameBytes.data(), exe.toUtf8().data())) + rdcstr host = m_Ctx.Replay().CurrentRemote()->Hostname; + if(RENDERDOC_PushLayerToInstalledAndroidApp(host.c_str(), exe.toUtf8().data())) { // Sucess! pushSucceeded = true; @@ -599,8 +599,8 @@ void CaptureDialog::androidWarn_mouseClick() // call into APK pull, patch, install routine, then continue LambdaThread *patch = new LambdaThread([this, exe, &patchSucceeded, &progress]() { - QByteArray hostnameBytes = m_Ctx.Replay().CurrentRemote()->Hostname.toUtf8(); - if(RENDERDOC_AddLayerToAndroidPackage(hostnameBytes.data(), exe.toUtf8().data(), &progress)) + rdcstr host = m_Ctx.Replay().CurrentRemote()->Hostname; + if(RENDERDOC_AddLayerToAndroidPackage(host.c_str(), exe.toUtf8().data(), &progress)) { // Sucess! patchSucceeded = true; @@ -955,7 +955,7 @@ CaptureSettings CaptureDialog::Settings() return ret; } -void CaptureDialog::SaveSettings(QString filename) +void CaptureDialog::SaveSettings(const rdcstr &filename) { QFile f(filename); if(f.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) @@ -990,7 +990,7 @@ void CaptureDialog::fillProcessList() } } -void CaptureDialog::SetExecutableFilename(const QString &filename) +void CaptureDialog::SetExecutableFilename(const rdcstr &filename) { QString fn = filename; @@ -1006,17 +1006,17 @@ void CaptureDialog::SetExecutableFilename(const QString &filename) } } -void CaptureDialog::SetWorkingDirectory(const QString &dir) +void CaptureDialog::SetWorkingDirectory(const rdcstr &dir) { ui->workDirPath->setText(dir); } -void CaptureDialog::SetCommandLine(const QString &cmd) +void CaptureDialog::SetCommandLine(const rdcstr &cmd) { ui->cmdline->setText(cmd); } -void CaptureDialog::LoadSettings(QString filename) +void CaptureDialog::LoadSettings(const rdcstr &filename) { QFile f(filename); if(f.open(QIODevice::ReadOnly | QIODevice::Text)) @@ -1064,7 +1064,7 @@ void CaptureDialog::UpdateGlobalHook() } } -void CaptureDialog::SetEnvironmentModifications(const QList &modifications) +void CaptureDialog::SetEnvironmentModifications(const rdcarray &modifications) { m_EnvModifications = modifications; diff --git a/qrenderdoc/Windows/Dialogs/CaptureDialog.h b/qrenderdoc/Windows/Dialogs/CaptureDialog.h index 9b12dc6e5..c75c7ca3e 100644 --- a/qrenderdoc/Windows/Dialogs/CaptureDialog.h +++ b/qrenderdoc/Windows/Dialogs/CaptureDialog.h @@ -44,10 +44,10 @@ class CaptureDialog : public QFrame, public ICaptureDialog public: typedef std::function &env, CaptureOptions opts, + const rdcarray &env, CaptureOptions opts, std::function callback)> OnCaptureMethod; - typedef std::function &env, const QString &name, + typedef std::function &env, const QString &name, CaptureOptions opts, std::function callback)> OnInjectMethod; @@ -60,18 +60,18 @@ public: bool IsInjectMode() override { return m_Inject; } void SetInjectMode(bool inject) override; - void SetExecutableFilename(const QString &filename) override; - void SetWorkingDirectory(const QString &dir) override; - void SetCommandLine(const QString &cmd) override; - void SetEnvironmentModifications(const QList &modifications) override; + void SetExecutableFilename(const rdcstr &filename) override; + void SetWorkingDirectory(const rdcstr &dir) override; + void SetCommandLine(const rdcstr &cmd) override; + void SetEnvironmentModifications(const rdcarray &modifications) override; void SetSettings(CaptureSettings settings) override; CaptureSettings Settings() override; void TriggerCapture() override; - void LoadSettings(QString filename) override; - void SaveSettings(QString filename) override; + void LoadSettings(const rdcstr &filename) override; + void SaveSettings(const rdcstr &filename) override; void UpdateGlobalHook() override; public slots: @@ -111,7 +111,7 @@ private: OnCaptureMethod m_CaptureCallback; OnInjectMethod m_InjectCallback; - QList m_EnvModifications; + rdcarray m_EnvModifications; bool m_Inject; void fillProcessList(); void initWarning(RDLabel *label); diff --git a/qrenderdoc/Windows/Dialogs/LiveCapture.cpp b/qrenderdoc/Windows/Dialogs/LiveCapture.cpp index 704207e94..8472d3cae 100644 --- a/qrenderdoc/Windows/Dialogs/LiveCapture.cpp +++ b/qrenderdoc/Windows/Dialogs/LiveCapture.cpp @@ -617,9 +617,9 @@ bool LiveCapture::checkAllowClose() // we either have to save or delete the capture. Make sure that if it's remote that we are able // to by having an active connection or replay context on that host. if(suppressRemoteWarning == false && (!m_Connection || !m_Connection->Connected()) && - !cap->local && - (!m_Ctx.Replay().CurrentRemote() || m_Ctx.Replay().CurrentRemote()->Hostname != m_Hostname || - !m_Ctx.Replay().CurrentRemote()->Connected)) + !cap->local && (!m_Ctx.Replay().CurrentRemote() || + QString(m_Ctx.Replay().CurrentRemote()->Hostname) != m_Hostname || + !m_Ctx.Replay().CurrentRemote()->Connected)) { QMessageBox::StandardButton res2 = RDDialog::question( this, tr("No active replay context"), @@ -670,9 +670,9 @@ void LiveCapture::openCapture(Capture *cap) { cap->opened = true; - if(!cap->local && - (!m_Ctx.Replay().CurrentRemote() || m_Ctx.Replay().CurrentRemote()->Hostname != m_Hostname || - !m_Ctx.Replay().CurrentRemote()->Connected)) + if(!cap->local && (!m_Ctx.Replay().CurrentRemote() || + QString(m_Ctx.Replay().CurrentRemote()->Hostname) != m_Hostname || + !m_Ctx.Replay().CurrentRemote()->Connected)) { RDDialog::critical( this, tr("No active replay context"), @@ -725,7 +725,8 @@ bool LiveCapture::saveCapture(Capture *cap) } else { - if(!m_Ctx.Replay().CurrentRemote() || m_Ctx.Replay().CurrentRemote()->Hostname != m_Hostname || + if(!m_Ctx.Replay().CurrentRemote() || + QString(m_Ctx.Replay().CurrentRemote()->Hostname) != m_Hostname || !m_Ctx.Replay().CurrentRemote()->Connected) { RDDialog::critical(this, tr("No active replay context"), @@ -949,7 +950,8 @@ void LiveCapture::connectionClosed() // to this machine as a remote context if(!cap->local) { - if(!m_Ctx.Replay().CurrentRemote() || m_Ctx.Replay().CurrentRemote()->Hostname != m_Hostname || + if(!m_Ctx.Replay().CurrentRemote() || + QString(m_Ctx.Replay().CurrentRemote()->Hostname) != m_Hostname || !m_Ctx.Replay().CurrentRemote()->Connected) return; } diff --git a/qrenderdoc/Windows/Dialogs/RemoteManager.cpp b/qrenderdoc/Windows/Dialogs/RemoteManager.cpp index cbb0c88fe..37e5335c5 100644 --- a/qrenderdoc/Windows/Dialogs/RemoteManager.cpp +++ b/qrenderdoc/Windows/Dialogs/RemoteManager.cpp @@ -145,7 +145,7 @@ void RemoteManager::setRemoteServerLive(RDTreeWidgetItem *node, bool live, bool host->ServerRunning = live; host->Busy = busy; - if(host->Hostname == lit("localhost")) + if(host->IsLocalhost()) { node->setIcon(0, QIcon()); node->setText(1, QString()); @@ -230,8 +230,6 @@ void RemoteManager::refreshHost(RDTreeWidgetItem *node) GUIInvoke::call( [this, node, host]() { setRemoteServerLive(node, host->ServerRunning, host->Busy); }); - QByteArray hostnameBytes = host->Hostname.toUtf8(); - uint32_t nextIdent = 0; for(;;) @@ -239,13 +237,13 @@ void RemoteManager::refreshHost(RDTreeWidgetItem *node) // just a sanity check to make sure we don't hit some unexpected case and infinite loop uint32_t prevIdent = nextIdent; - nextIdent = RENDERDOC_EnumerateRemoteTargets(hostnameBytes.data(), nextIdent); + nextIdent = RENDERDOC_EnumerateRemoteTargets(host->Hostname.c_str(), nextIdent); if(nextIdent == 0 || prevIdent >= nextIdent) break; ITargetControl *conn = - RENDERDOC_CreateTargetControl(hostnameBytes.data(), nextIdent, username.data(), false); + RENDERDOC_CreateTargetControl(host->Hostname.c_str(), nextIdent, username.data(), false); if(conn) { @@ -337,7 +335,7 @@ void RemoteManager::updateConnectButton() if(host) { - if(host->Hostname == lit("localhost")) + if(host->IsLocalhost()) { ui->connect->setText(tr("Run Server")); ui->connect->setEnabled(false); @@ -373,7 +371,8 @@ void RemoteManager::addNewHost() for(int i = 0; i < m_Ctx.Config().RemoteHosts.count(); i++) { - if(m_Ctx.Config().RemoteHosts[i]->Hostname.compare(host, Qt::CaseInsensitive) == 0) + QString hostname = m_Ctx.Config().RemoteHosts[i]->Hostname; + if(hostname.compare(host, Qt::CaseInsensitive) == 0) { found = true; break; @@ -457,7 +456,7 @@ void RemoteManager::on_hosts_itemSelectionChanged() ui->addUpdateHost->setText(tr("Update")); - if(host->Hostname == lit("localhost") || host->IsHostADB()) + if(host->IsLocalhost() || host->IsHostADB()) { // localhost and android hosts cannot be updated or have their run command changed ui->addUpdateHost->setEnabled(false); @@ -612,7 +611,7 @@ void RemoteManager::on_connect_clicked() { IRemoteServer *server = NULL; ReplayStatus status = - RENDERDOC_CreateRemoteServerConnection(host->Hostname.toUtf8().data(), 0, &server); + RENDERDOC_CreateRemoteServerConnection(host->Hostname.c_str(), 0, &server); if(server) server->ShutdownServerAndConnection(); setRemoteServerLive(node, false, false); @@ -670,9 +669,9 @@ void RemoteManager::on_deleteHost_clicked() if(res == QMessageBox::Yes) { - int idx = m_Ctx.Config().RemoteHosts.indexOf(host); + size_t idx = m_Ctx.Config().RemoteHosts.indexOf(host); // the host will be removed in queueDelete. - m_Ctx.Config().RemoteHosts.removeAt(idx); + m_Ctx.Config().RemoteHosts.erase(idx); m_Ctx.Config().Save(); item->clear(); diff --git a/qrenderdoc/Windows/Dialogs/SettingsDialog.cpp b/qrenderdoc/Windows/Dialogs/SettingsDialog.cpp index d58c9f1b3..38339070d 100644 --- a/qrenderdoc/Windows/Dialogs/SettingsDialog.cpp +++ b/qrenderdoc/Windows/Dialogs/SettingsDialog.cpp @@ -243,9 +243,9 @@ void SettingsDialog::on_chooseSearchPaths_clicked() OrderedListEditor listEd(tr("Shader debug info search paths"), tr("Search Path"), BrowseMode::Folder, this); - listEd.setItems(m_Ctx.Config() - .GetConfigSetting(lit("shader.debug.searchPaths")) - .split(QLatin1Char(';'), QString::SkipEmptyParts)); + QString setting = m_Ctx.Config().GetConfigSetting("shader.debug.searchPaths"); + + listEd.setItems(setting.split(QLatin1Char(';'), QString::SkipEmptyParts)); int res = RDDialog::show(&listEd); diff --git a/qrenderdoc/Windows/EventBrowser.cpp b/qrenderdoc/Windows/EventBrowser.cpp index f3251eebd..a930be1e9 100644 --- a/qrenderdoc/Windows/EventBrowser.cpp +++ b/qrenderdoc/Windows/EventBrowser.cpp @@ -924,7 +924,7 @@ void EventBrowser::clearBookmarks() void EventBrowser::repopulateBookmarks() { - const QList bookmarks = m_Ctx.GetBookmarks(); + const rdcarray bookmarks = m_Ctx.GetBookmarks(); // add any bookmark markers that we don't have for(const EventBookmark &mark : bookmarks) @@ -1002,7 +1002,7 @@ void EventBrowser::toggleBookmark(uint32_t EID) void EventBrowser::jumpToBookmark(int idx) { - const QList bookmarks = m_Ctx.GetBookmarks(); + const rdcarray bookmarks = m_Ctx.GetBookmarks(); if(idx < 0 || idx >= bookmarks.count() || !m_Ctx.IsCaptureLoaded()) return; diff --git a/qrenderdoc/Windows/MainWindow.cpp b/qrenderdoc/Windows/MainWindow.cpp index 737de0bdc..b94f9b3f0 100644 --- a/qrenderdoc/Windows/MainWindow.cpp +++ b/qrenderdoc/Windows/MainWindow.cpp @@ -323,8 +323,9 @@ void MainWindow::LoadFromFilename(const QString &filename, bool temporary) } void MainWindow::OnCaptureTrigger(const QString &exe, const QString &workingDir, - const QString &cmdLine, const QList &env, - CaptureOptions opts, std::function callback) + const QString &cmdLine, + const rdcarray &env, CaptureOptions opts, + std::function callback) { if(!PromptCloseCapture()) return; @@ -345,10 +346,9 @@ void MainWindow::OnCaptureTrigger(const QString &exe, const QString &workingDir, } LiveCapture *live = new LiveCapture( - m_Ctx, - m_Ctx.Replay().CurrentRemote() ? m_Ctx.Replay().CurrentRemote()->Hostname : QString(), - m_Ctx.Replay().CurrentRemote() ? m_Ctx.Replay().CurrentRemote()->Name() : QString(), ret, - this, this); + m_Ctx, m_Ctx.Replay().CurrentRemote() ? m_Ctx.Replay().CurrentRemote()->Hostname : "", + m_Ctx.Replay().CurrentRemote() ? m_Ctx.Replay().CurrentRemote()->Name() : "", ret, this, + this); ShowLiveCapture(live); callback(live); }); @@ -365,20 +365,17 @@ void MainWindow::OnCaptureTrigger(const QString &exe, const QString &workingDir, th->deleteLater(); } -void MainWindow::OnInjectTrigger(uint32_t PID, const QList &env, +void MainWindow::OnInjectTrigger(uint32_t PID, const rdcarray &env, const QString &name, CaptureOptions opts, std::function callback) { if(!PromptCloseCapture()) return; - rdcarray envList = env.toVector().toStdVector(); - - LambdaThread *th = new LambdaThread([this, PID, envList, name, opts, callback]() { + LambdaThread *th = new LambdaThread([this, PID, env, name, opts, callback]() { QString capturefile = m_Ctx.TempCaptureFilename(name); - uint32_t ret = - RENDERDOC_InjectIntoProcess(PID, envList, capturefile.toUtf8().data(), opts, false); + uint32_t ret = RENDERDOC_InjectIntoProcess(PID, env, capturefile.toUtf8().data(), opts, false); GUIInvoke::call([this, PID, ret, callback]() { if(ret == 0) @@ -510,11 +507,11 @@ void MainWindow::LoadCapture(const QString &filename, bool temporary, bool local { support = ReplaySupport::Unsupported; - QStringList remoteDrivers = m_Ctx.Replay().GetRemoteSupport(); + rdcarray remoteDrivers = m_Ctx.Replay().GetRemoteSupport(); - for(const QString &d : remoteDrivers) + for(const rdcstr &d : remoteDrivers) { - if(driver == d) + if(driver == QString(d)) support = ReplaySupport::Supported; } } @@ -796,7 +793,7 @@ void MainWindow::PopulateRecentCaptureFiles() ui->menu_Recent_Capture_Files->setEnabled(false); int idx = 1; - for(int i = m_Ctx.Config().RecentCaptureFiles.size() - 1; i >= 0; i--) + for(int i = m_Ctx.Config().RecentCaptureFiles.count() - 1; i >= 0; i--) { const QString &filename = m_Ctx.Config().RecentCaptureFiles[i]; ui->menu_Recent_Capture_Files->addAction(QFormatStr("&%1 %2").arg(idx).arg(filename), @@ -823,7 +820,7 @@ void MainWindow::PopulateRecentCaptureSettings() ui->menu_Recent_Capture_Settings->setEnabled(false); int idx = 1; - for(int i = m_Ctx.Config().RecentCaptureSettings.size() - 1; i >= 0; i--) + for(int i = m_Ctx.Config().RecentCaptureSettings.count() - 1; i >= 0; i--) { const QString &filename = m_Ctx.Config().RecentCaptureSettings[i]; ui->menu_Recent_Capture_Settings->addAction(QFormatStr("&%1 %2").arg(idx).arg(filename), @@ -1123,7 +1120,7 @@ void MainWindow::FillRemotesMenu(QMenu *menu, bool includeLocalhost) RemoteHost *host = m_Ctx.Config().RemoteHosts[i]; // add localhost at the end - if(host->Hostname == lit("localhost")) + if(host->IsLocalhost()) continue; QAction *action = new QAction(menu); @@ -1381,7 +1378,7 @@ void MainWindow::OnEventChanged(uint32_t eventID) { } -void MainWindow::RegisterShortcut(const QString &shortcut, QWidget *widget, ShortcutCallback callback) +void MainWindow::RegisterShortcut(const rdcstr &shortcut, QWidget *widget, ShortcutCallback callback) { QKeySequence ks = QKeySequence::fromString(shortcut); @@ -1401,7 +1398,7 @@ void MainWindow::RegisterShortcut(const QString &shortcut, QWidget *widget, Shor } } -void MainWindow::UnregisterShortcut(const QString &shortcut, QWidget *widget) +void MainWindow::UnregisterShortcut(const rdcstr &shortcut, QWidget *widget) { if(widget) { diff --git a/qrenderdoc/Windows/MainWindow.h b/qrenderdoc/Windows/MainWindow.h index 42a39c51e..f4d0322c6 100644 --- a/qrenderdoc/Windows/MainWindow.h +++ b/qrenderdoc/Windows/MainWindow.h @@ -55,8 +55,8 @@ public: // IMainWindow QWidget *Widget() override { return this; } - void RegisterShortcut(const QString &shortcut, QWidget *widget, ShortcutCallback callback) override; - void UnregisterShortcut(const QString &shortcut, QWidget *widget) override; + void RegisterShortcut(const rdcstr &shortcut, QWidget *widget, ShortcutCallback callback) override; + void UnregisterShortcut(const rdcstr &shortcut, QWidget *widget) override; // ICaptureViewer void OnCaptureLoaded() override; void OnCaptureClosed() override; @@ -78,10 +78,11 @@ public: QString GetSavePath(); void OnCaptureTrigger(const QString &exe, const QString &workingDir, const QString &cmdLine, - const QList &env, CaptureOptions opts, + const rdcarray &env, CaptureOptions opts, std::function callback); - void OnInjectTrigger(uint32_t PID, const QList &env, const QString &name, - CaptureOptions opts, std::function callback); + void OnInjectTrigger(uint32_t PID, const rdcarray &env, + const QString &name, CaptureOptions opts, + std::function callback); void ShowLiveCapture(LiveCapture *live); void LiveCaptureClosed(LiveCapture *live); diff --git a/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp index 9a156698b..67215c3ca 100644 --- a/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp @@ -2245,22 +2245,21 @@ void D3D11PipelineStateViewer::shaderEdit_clicked() QString entryFunc = lit("EditedShader%1S").arg(ToQStr(stage->stage, GraphicsAPI::D3D11)[0]); - QString mainfile; + rdcstrpairs files; - QStringMap files; - - bool hasOrigSource = m_Common.PrepareShaderEditing(shaderDetails, entryFunc, files, mainfile); + bool hasOrigSource = m_Common.PrepareShaderEditing(shaderDetails, entryFunc, files); if(!hasOrigSource) { - mainfile = lit("generated.hlsl"); - files[mainfile] = m_Common.GenerateHLSLStub(shaderDetails, entryFunc); + files.clear(); + files.push_back(make_rdcpair( + "generated.hlsl", m_Common.GenerateHLSLStub(shaderDetails, entryFunc))); } if(files.empty()) return; - m_Common.EditShader(stage->stage, stage->Object, shaderDetails, entryFunc, files, mainfile); + m_Common.EditShader(stage->stage, stage->Object, shaderDetails, entryFunc, files); } void D3D11PipelineStateViewer::shaderSave_clicked() @@ -2307,7 +2306,8 @@ QVariantList D3D11PipelineStateViewer::exportViewHTML(const D3D11Pipe::View &vie } } - QString name = view.Resource == ResourceId() ? tr("Empty") : m_Ctx.GetResourceName(view.Resource); + QString name = + view.Resource == ResourceId() ? tr("Empty") : QString(m_Ctx.GetResourceName(view.Resource)); QString typeName = tr("Unknown"); QString format = tr("Unknown"); uint64_t w = 1; diff --git a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp index 315019e99..7e04a9bec 100644 --- a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp @@ -2080,22 +2080,21 @@ void D3D12PipelineStateViewer::shaderEdit_clicked() QString entryFunc = lit("EditedShader%1S").arg(ToQStr(stage->stage, GraphicsAPI::D3D12)[0]); - QString mainfile; + rdcstrpairs files; - QStringMap files; - - bool hasOrigSource = m_Common.PrepareShaderEditing(shaderDetails, entryFunc, files, mainfile); + bool hasOrigSource = m_Common.PrepareShaderEditing(shaderDetails, entryFunc, files); if(!hasOrigSource) { - mainfile = lit("generated.hlsl"); - files[mainfile] = m_Common.GenerateHLSLStub(shaderDetails, entryFunc); + files.clear(); + files.push_back(make_rdcpair( + "generated.hlsl", m_Common.GenerateHLSLStub(shaderDetails, entryFunc))); } if(files.empty()) return; - m_Common.EditShader(stage->stage, stage->Object, shaderDetails, entryFunc, files, mainfile); + m_Common.EditShader(stage->stage, stage->Object, shaderDetails, entryFunc, files); } void D3D12PipelineStateViewer::shaderSave_clicked() @@ -2117,7 +2116,8 @@ QVariantList D3D12PipelineStateViewer::exportViewHTML(const D3D12Pipe::View &vie const ShaderResource *shaderInput, const QString &extraParams) { - QString name = view.Resource == ResourceId() ? tr("Empty") : m_Ctx.GetResourceName(view.Resource); + QString name = + view.Resource == ResourceId() ? tr("Empty") : QString(m_Ctx.GetResourceName(view.Resource)); QString typeName = tr("Unknown"); QString format = tr("Unknown"); uint64_t w = 1; diff --git a/qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.cpp index 908e0e09a..53977e024 100644 --- a/qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.cpp @@ -2215,26 +2215,21 @@ void GLPipelineStateViewer::shaderEdit_clicked() QString entryFunc = lit("EditedShader%1S").arg(ToQStr(stage->stage, GraphicsAPI::OpenGL)[0]); - QString mainfile; + rdcstrpairs files; - QStringMap files; - - bool hasOrigSource = m_Common.PrepareShaderEditing(shaderDetails, entryFunc, files, mainfile); + bool hasOrigSource = m_Common.PrepareShaderEditing(shaderDetails, entryFunc, files); if(!hasOrigSource) { // this would only happen if the GL program is uploading SPIR-V instead of GLSL. - QString glsl = lit("// TODO - disassemble SPIR-V"); - - mainfile = lit("generated.glsl"); - - files[mainfile] = glsl; + files.clear(); + files.push_back(make_rdcpair("generated.glsl", "// TODO - disassemble SPIR-V")); } if(files.empty()) return; - m_Common.EditShader(stage->stage, stage->Object, shaderDetails, entryFunc, files, mainfile); + m_Common.EditShader(stage->stage, stage->Object, shaderDetails, entryFunc, files); } void GLPipelineStateViewer::shaderSave_clicked() diff --git a/qrenderdoc/Windows/PipelineState/PipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/PipelineStateViewer.cpp index 6b40be3ce..8609a0b34 100644 --- a/qrenderdoc/Windows/PipelineState/PipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/PipelineStateViewer.cpp @@ -540,8 +540,7 @@ void PipelineStateViewer::setMeshViewPixmap(RDLabel *meshView) } bool PipelineStateViewer::PrepareShaderEditing(const ShaderReflection *shaderDetails, - QString &entryFunc, QStringMap &files, - QString &mainfile) + QString &entryFunc, rdcstrpairs &files) { if(!shaderDetails->DebugInfo.files.empty()) { @@ -549,7 +548,7 @@ bool PipelineStateViewer::PrepareShaderEditing(const ShaderReflection *shaderDet QStringList uniqueFiles; - for(auto &s : shaderDetails->DebugInfo.files) + for(const ShaderSourceFile &s : shaderDetails->DebugInfo.files) { QString filename = s.Filename; if(uniqueFiles.contains(filename.toLower())) @@ -559,11 +558,9 @@ bool PipelineStateViewer::PrepareShaderEditing(const ShaderReflection *shaderDet } uniqueFiles.push_back(filename.toLower()); - files[filename] = s.Contents; + files.push_back(make_rdcpair(s.Filename, s.Contents)); } - mainfile = shaderDetails->DebugInfo.files[0].Filename; - return true; } @@ -717,17 +714,17 @@ QString PipelineStateViewer::GenerateHLSLStub(const ShaderReflection *shaderDeta } void PipelineStateViewer::EditShader(ShaderStage shaderType, ResourceId id, - const ShaderReflection *shaderDetails, const QString &entryFunc, - const QStringMap &files, const QString &mainfile) + const ShaderReflection *shaderDetails, + const QString &entryFunc, const rdcstrpairs &files) { ANALYTIC_SET(UIFeatures.ShaderEditing, true); IShaderViewer *sv = m_Ctx.EditShader( false, entryFunc, files, // save callback - [entryFunc, mainfile, shaderType, id, shaderDetails]( - ICaptureContext *ctx, IShaderViewer *viewer, const QStringMap &updatedfiles) { - QString compileSource = updatedfiles[mainfile]; + [entryFunc, shaderType, id, shaderDetails](ICaptureContext *ctx, IShaderViewer *viewer, + const rdcstrpairs &updatedfiles) { + QString compileSource = updatedfiles[0].second; // try and match up #includes against the files that we have. This isn't always // possible as fxc only seems to include the source for files if something in @@ -789,19 +786,25 @@ void PipelineStateViewer::EditShader(ShaderStage shaderType, ResourceId id, QString fileText; // look for exact match first - if(updatedfiles.contains(fname)) + for(int i = 0; i < updatedfiles.count(); i++) { - fileText = updatedfiles[fname]; + if(QString(updatedfiles[i].first) == fname) + { + fileText = updatedfiles[i].second; + break; + } } - else + + if(fileText.isEmpty()) { QString search = QFileInfo(fname).fileName(); + // if not, try and find the same filename (this is not proper include handling!) - for(const QString &k : updatedfiles.keys()) + for(const rdcstrpair &kv : updatedfiles) { - if(QFileInfo(k).fileName().compare(search, Qt::CaseInsensitive) == 0) + if(QFileInfo(kv.first).fileName().compare(search, Qt::CaseInsensitive) == 0) { - fileText = updatedfiles[k]; + fileText = kv.second; break; } } @@ -818,8 +821,11 @@ void PipelineStateViewer::EditShader(ShaderStage shaderType, ResourceId id, offs = compileSource.indexOf(lit("#include")); } - if(updatedfiles.contains(lit("@cmdline"))) - compileSource = updatedfiles[lit("@cmdline")] + lit("\n\n") + compileSource; + for(const rdcstrpair &kv : updatedfiles) + { + if(kv.first == "@cmdline") + compileSource = QString(kv.second) + lit("\n\n") + compileSource; + } // invoke off to the ReplayController to replace the capture's shader // with our edited one diff --git a/qrenderdoc/Windows/PipelineState/PipelineStateViewer.h b/qrenderdoc/Windows/PipelineState/PipelineStateViewer.h index 41ad2ad11..7be8d715d 100644 --- a/qrenderdoc/Windows/PipelineState/PipelineStateViewer.h +++ b/qrenderdoc/Windows/PipelineState/PipelineStateViewer.h @@ -67,10 +67,10 @@ public: void setPersistData(const QVariant &persistData); bool PrepareShaderEditing(const ShaderReflection *shaderDetails, QString &entryFunc, - QStringMap &files, QString &mainfile); + rdcstrpairs &files); QString GenerateHLSLStub(const ShaderReflection *shaderDetails, const QString &entryFunc); void EditShader(ShaderStage shaderType, ResourceId id, const ShaderReflection *shaderDetails, - const QString &entryFunc, const QStringMap &files, const QString &mainfile); + const QString &entryFunc, const rdcstrpairs &files); void setTopologyDiagram(QLabel *diagram, Topology topo); void setMeshViewPixmap(RDLabel *meshView); diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp index 2d1f30c6e..a3a97ad3a 100644 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp @@ -2309,11 +2309,9 @@ void VulkanPipelineStateViewer::shaderEdit_clicked() QString entryFunc = lit("EditedShader%1S").arg(ToQStr(stage->stage, GraphicsAPI::Vulkan)[0]); - QString mainfile; + rdcstrpairs files; - QStringMap files; - - bool hasOrigSource = m_Common.PrepareShaderEditing(shaderDetails, entryFunc, files, mainfile); + bool hasOrigSource = m_Common.PrepareShaderEditing(shaderDetails, entryFunc, files); if(hasOrigSource) { @@ -2327,28 +2325,27 @@ void VulkanPipelineStateViewer::shaderEdit_clicked() if(!m_Ctx.Config().SPIRVDisassemblers.isEmpty()) glsl = disassembleSPIRV(shaderDetails); - mainfile = lit("generated.glsl"); - - files[mainfile] = glsl; - - if(glsl.isEmpty()) + if(!glsl.isEmpty()) { - m_Ctx.Replay().AsyncInvoke( - [this, stage, pipe, shaderDetails, entryFunc, mainfile](IReplayController *r) { - rdcstr disasm = r->DisassembleShader(pipe, shaderDetails, ""); + files.clear(); + files.push_back(make_rdcpair("generated.glsl", glsl)); + } + else + { + m_Ctx.Replay().AsyncInvoke([this, stage, pipe, shaderDetails, entryFunc](IReplayController *r) { + rdcstr disasm = r->DisassembleShader(pipe, shaderDetails, ""); - GUIInvoke::call([this, stage, shaderDetails, entryFunc, mainfile, disasm]() { - QStringMap fileMap; - fileMap[mainfile] = disasm; - m_Common.EditShader(stage->stage, stage->Object, shaderDetails, entryFunc, fileMap, - mainfile); - }); - }); + GUIInvoke::call([this, stage, shaderDetails, entryFunc, disasm]() { + rdcstrpairs fileMap; + fileMap.push_back(make_rdcpair("generated.glsl", disasm)); + m_Common.EditShader(stage->stage, stage->Object, shaderDetails, entryFunc, fileMap); + }); + }); return; } } - m_Common.EditShader(stage->stage, stage->Object, shaderDetails, entryFunc, files, mainfile); + m_Common.EditShader(stage->stage, stage->Object, shaderDetails, entryFunc, files); } QString VulkanPipelineStateViewer::disassembleSPIRV(const ShaderReflection *shaderDetails) @@ -2376,7 +2373,7 @@ QString VulkanPipelineStateViewer::disassembleSPIRV(const ShaderReflection *shad return QString(); } - if(!disasm.args.contains(lit("{spv_bin}"))) + if(!QString(disasm.args).contains(lit("{spv_bin}"))) { RDDialog::critical( this, tr("Wrongly configured disassembler"), @@ -2389,7 +2386,7 @@ QString VulkanPipelineStateViewer::disassembleSPIRV(const ShaderReflection *shad QString args = disasm.args; - bool writesToFile = disasm.args.contains(lit("{spv_disas}")); + bool writesToFile = args.contains(lit("{spv_disas}")); args.replace(lit("{spv_bin}"), spv_bin_file); args.replace(lit("{spv_disas}"), spv_disas_file); diff --git a/qrenderdoc/Windows/PythonShell.cpp b/qrenderdoc/Windows/PythonShell.cpp index 4972ecfae..4c93c076e 100644 --- a/qrenderdoc/Windows/PythonShell.cpp +++ b/qrenderdoc/Windows/PythonShell.cpp @@ -46,7 +46,7 @@ struct CaptureContextInvoker : ICaptureContext // pass-through functions that don't need the UI thread /////////////////////////////////////////////////////////////////////// // - virtual QString TempCaptureFilename(QString appname) override + virtual rdcstr TempCaptureFilename(const rdcstr &appname) override { return m_Ctx.TempCaptureFilename(appname); } @@ -55,7 +55,7 @@ struct CaptureContextInvoker : ICaptureContext virtual bool IsCaptureLocal() override { return m_Ctx.IsCaptureLocal(); } virtual bool IsCaptureTemporary() override { return m_Ctx.IsCaptureTemporary(); } virtual bool IsCaptureLoading() override { return m_Ctx.IsCaptureLoading(); } - virtual QString GetCaptureFilename() override { return m_Ctx.GetCaptureFilename(); } + virtual rdcstr GetCaptureFilename() override { return m_Ctx.GetCaptureFilename(); } virtual CaptureModifications GetCaptureModifications() override { return m_Ctx.GetCaptureModifications(); @@ -83,7 +83,7 @@ struct CaptureContextInvoker : ICaptureContext { return m_Ctx.GetResources(); } - virtual QString GetResourceName(ResourceId id) override { return m_Ctx.GetResourceName(id); } + virtual rdcstr GetResourceName(ResourceId id) override { return m_Ctx.GetResourceName(id); } virtual bool IsAutogeneratedName(ResourceId id) override { return m_Ctx.IsAutogeneratedName(id); } virtual bool HasResourceCustomName(ResourceId id) override { @@ -104,11 +104,11 @@ struct CaptureContextInvoker : ICaptureContext { return m_Ctx.FillWindowingData(winId); } - virtual const QVector &DebugMessages() override { return m_Ctx.DebugMessages(); } + virtual const rdcarray &DebugMessages() override { return m_Ctx.DebugMessages(); } virtual int UnreadMessageCount() override { return m_Ctx.UnreadMessageCount(); } virtual void MarkMessagesRead() override { return m_Ctx.MarkMessagesRead(); } - virtual QString GetNotes(const QString &key) override { return m_Ctx.GetNotes(key); } - virtual QList GetBookmarks() override { return m_Ctx.GetBookmarks(); } + virtual rdcstr GetNotes(const rdcstr &key) override { return m_Ctx.GetNotes(key); } + virtual rdcarray GetBookmarks() override { return m_Ctx.GetBookmarks(); } virtual const D3D11Pipe::State &CurD3D11PipelineState() override { return m_Ctx.CurD3D11PipelineState(); @@ -156,12 +156,12 @@ struct CaptureContextInvoker : ICaptureContext return (m_Ctx.*ptr)(params...); } - virtual void LoadCapture(const QString &capture, const QString &origFilename, bool temporary, + virtual void LoadCapture(const rdcstr &capture, const rdcstr &origFilename, bool temporary, bool local) override { InvokeVoidFunction(&ICaptureContext::LoadCapture, capture, origFilename, temporary, local); } - virtual bool SaveCaptureTo(const QString &capture) override + virtual bool SaveCaptureTo(const rdcstr &capture) override { return InvokeRetFunction(&ICaptureContext::SaveCaptureTo, capture); } @@ -170,7 +170,7 @@ struct CaptureContextInvoker : ICaptureContext InvokeVoidFunction(&ICaptureContext::RecompressCapture); } virtual void CloseCapture() override { InvokeVoidFunction(&ICaptureContext::CloseCapture); } - virtual void SetEventID(const QVector &exclude, uint32_t selectedEventID, + virtual void SetEventID(const rdcarray &exclude, uint32_t selectedEventID, uint32_t eventID, bool force = false) override { InvokeVoidFunction(&ICaptureContext::SetEventID, exclude, selectedEventID, eventID, force); @@ -188,11 +188,11 @@ struct CaptureContextInvoker : ICaptureContext { InvokeVoidFunction(&ICaptureContext::AddMessages, msgs); } - virtual void SetResourceCustomName(ResourceId id, const QString &name) override + virtual void SetResourceCustomName(ResourceId id, const rdcstr &name) override { InvokeVoidFunction(&ICaptureContext::SetResourceCustomName, id, name); } - virtual void SetNotes(const QString &key, const QString &contents) override + virtual void SetNotes(const rdcstr &key, const rdcstr &contents) override { InvokeVoidFunction(&ICaptureContext::SetNotes, key, contents); } @@ -355,8 +355,9 @@ struct CaptureContextInvoker : ICaptureContext { InvokeVoidFunction(&ICaptureContext::ShowResourceInspector); } - virtual IShaderViewer *EditShader(bool customShader, const QString &entryPoint, - const QStringMap &files, IShaderViewer::SaveCallback saveCallback, + virtual IShaderViewer *EditShader(bool customShader, const rdcstr &entryPoint, + const rdcstrpairs &files, + IShaderViewer::SaveCallback saveCallback, IShaderViewer::CloseCallback closeCallback) override { return InvokeRetFunction(&ICaptureContext::EditShader, customShader, @@ -365,7 +366,7 @@ struct CaptureContextInvoker : ICaptureContext virtual IShaderViewer *DebugShader(const ShaderBindpointMapping *bind, const ShaderReflection *shader, ResourceId pipeline, - ShaderDebugTrace *trace, const QString &debugContext) override + ShaderDebugTrace *trace, const rdcstr &debugContext) override { return InvokeRetFunction(&ICaptureContext::DebugShader, bind, shader, pipeline, trace, debugContext); @@ -377,14 +378,14 @@ struct CaptureContextInvoker : ICaptureContext } virtual IBufferViewer *ViewBuffer(uint64_t byteOffset, uint64_t byteSize, ResourceId id, - const QString &format = QString()) override + const rdcstr &format = "") override { return InvokeRetFunction(&ICaptureContext::ViewBuffer, byteOffset, byteSize, id, format); } virtual IBufferViewer *ViewTextureAsBuffer(uint32_t arrayIdx, uint32_t mip, ResourceId id, - const QString &format = QString()) override + const rdcstr &format = "") override { return InvokeRetFunction(&ICaptureContext::ViewTextureAsBuffer, arrayIdx, mip, id, format); @@ -404,7 +405,7 @@ struct CaptureContextInvoker : ICaptureContext display); } - virtual QWidget *CreateBuiltinWindow(const QString &objectName) override + virtual QWidget *CreateBuiltinWindow(const rdcstr &objectName) override { return InvokeRetFunction(&ICaptureContext::CreateBuiltinWindow, objectName); } diff --git a/qrenderdoc/Windows/ShaderViewer.cpp b/qrenderdoc/Windows/ShaderViewer.cpp index 12885634a..3424bb803 100644 --- a/qrenderdoc/Windows/ShaderViewer.cpp +++ b/qrenderdoc/Windows/ShaderViewer.cpp @@ -197,7 +197,7 @@ ShaderViewer::ShaderViewer(ICaptureContext &ctx, QWidget *parent) m_Ctx.AddCaptureViewer(this); } -void ShaderViewer::editShader(bool customShader, const QString &entryPoint, const QStringMap &files) +void ShaderViewer::editShader(bool customShader, const QString &entryPoint, const rdcstrpairs &files) { m_Scintillas.removeOne(m_DisassemblyView); ui->docking->removeToolWindow(m_DisassemblyFrame); @@ -226,10 +226,10 @@ void ShaderViewer::editShader(bool customShader, const QString &entryPoint, cons QString title; QWidget *sel = NULL; - for(const QString &f : files.keys()) + for(const rdcstrpair &kv : files) { - QString name = QFileInfo(f).fileName(); - QString text = files[f]; + QString name = QFileInfo(kv.first).fileName(); + QString text = kv.second; ScintillaEdit *scintilla = AddFileScintilla(name, text); @@ -246,7 +246,7 @@ void ShaderViewer::editShader(bool customShader, const QString &entryPoint, cons [this]() { on_save_clicked(); }); QWidget *w = (QWidget *)scintilla; - w->setProperty("filename", f); + w->setProperty("filename", kv.first); if(text.contains(entryPoint)) sel = scintilla; @@ -1191,10 +1191,8 @@ void ShaderViewer::updateDebugging() } } - QMap> rw = - m_Ctx.CurPipelineState().GetReadWriteResources(m_Stage); - QMap> ro = - m_Ctx.CurPipelineState().GetReadOnlyResources(m_Stage); + rdcarray rw = m_Ctx.CurPipelineState().GetReadWriteResources(m_Stage); + rdcarray ro = m_Ctx.CurPipelineState().GetReadOnlyResources(m_Stage); bool tree = false; @@ -1207,10 +1205,15 @@ void ShaderViewer::updateDebugging() if(!bind.used) continue; + int idx = rw.indexOf(bind); + + if(idx < 0 || rw[idx].Resources.isEmpty()) + continue; + if(bind.arraySize == 1) { - RDTreeWidgetItem *node = - makeResourceRegister(bind, 0, rw[bind][0], m_ShaderDetails->ReadWriteResources[i]); + RDTreeWidgetItem *node = makeResourceRegister(bind, 0, rw[idx].Resources[0], + m_ShaderDetails->ReadWriteResources[i]); if(node) ui->constants->addTopLevelItem(node); } @@ -1221,8 +1224,8 @@ void ShaderViewer::updateDebugging() QFormatStr("[%1]").arg(bind.arraySize), QString()}); for(uint32_t a = 0; a < bind.arraySize; a++) - node->addChild( - makeResourceRegister(bind, a, rw[bind][a], m_ShaderDetails->ReadWriteResources[i])); + node->addChild(makeResourceRegister(bind, a, rw[idx].Resources[a], + m_ShaderDetails->ReadWriteResources[i])); tree = true; @@ -1239,10 +1242,15 @@ void ShaderViewer::updateDebugging() if(!bind.used) continue; + int idx = ro.indexOf(bind); + + if(idx < 0 || ro[idx].Resources.isEmpty()) + continue; + if(bind.arraySize == 1) { - RDTreeWidgetItem *node = - makeResourceRegister(bind, 0, ro[bind][0], m_ShaderDetails->ReadOnlyResources[i]); + RDTreeWidgetItem *node = makeResourceRegister(bind, 0, ro[idx].Resources[0], + m_ShaderDetails->ReadOnlyResources[i]); if(node) ui->constants->addTopLevelItem(node); } @@ -1253,8 +1261,8 @@ void ShaderViewer::updateDebugging() QFormatStr("[%1]").arg(bind.arraySize), QString()}); for(uint32_t a = 0; a < bind.arraySize; a++) - node->addChild( - makeResourceRegister(bind, a, ro[bind][a], m_ShaderDetails->ReadOnlyResources[i])); + node->addChild(makeResourceRegister(bind, a, ro[idx].Resources[a], + m_ShaderDetails->ReadOnlyResources[i])); tree = true; @@ -1550,12 +1558,12 @@ void ShaderViewer::ToggleBreakpoint(int instruction) } } -void ShaderViewer::ShowErrors(const QString &errors) +void ShaderViewer::ShowErrors(const rdcstr &errors) { if(m_Errors) { m_Errors->setReadOnly(false); - m_Errors->setText(errors.toUtf8().data()); + m_Errors->setText(errors.c_str()); m_Errors->setReadOnly(true); } } @@ -2070,11 +2078,12 @@ void ShaderViewer::on_save_clicked() if(m_SaveCallback) { - QMap files; + rdcstrpairs files; for(ScintillaEdit *s : m_Scintillas) { QWidget *w = (QWidget *)s; - files[w->property("filename").toString()] = QString::fromUtf8(s->getText(s->textLength() + 1)); + files.push_back(make_rdcpair( + w->property("filename").toString(), QString::fromUtf8(s->getText(s->textLength() + 1)))); } m_SaveCallback(&m_Ctx, this, files); } diff --git a/qrenderdoc/Windows/ShaderViewer.h b/qrenderdoc/Windows/ShaderViewer.h index 986d05f3a..08064b360 100644 --- a/qrenderdoc/Windows/ShaderViewer.h +++ b/qrenderdoc/Windows/ShaderViewer.h @@ -60,8 +60,9 @@ class ShaderViewer : public QFrame, public IShaderViewer, public ICaptureViewer Q_OBJECT public: - static IShaderViewer *EditShader(ICaptureContext &ctx, bool customShader, const QString &entryPoint, - const QStringMap &files, IShaderViewer::SaveCallback saveCallback, + static IShaderViewer *EditShader(ICaptureContext &ctx, bool customShader, + const QString &entryPoint, const rdcstrpairs &files, + IShaderViewer::SaveCallback saveCallback, IShaderViewer::CloseCallback closeCallback, QWidget *parent) { ShaderViewer *ret = new ShaderViewer(ctx, parent); @@ -96,7 +97,7 @@ public: virtual void ToggleBreakpoint(int instruction = -1) override; - virtual void ShowErrors(const QString &errors) override; + virtual void ShowErrors(const rdcstr &errors) override; // ICaptureViewer void OnCaptureLoaded() override; @@ -147,7 +148,7 @@ public slots: private: explicit ShaderViewer(ICaptureContext &ctx, QWidget *parent = 0); - void editShader(bool customShader, const QString &entryPoint, const QStringMap &files); + void editShader(bool customShader, const QString &entryPoint, const rdcstrpairs &files); void debugShader(const ShaderBindpointMapping *bind, const ShaderReflection *shader, ResourceId pipeline, ShaderDebugTrace *trace, const QString &debugContext); bool eventFilter(QObject *watched, QEvent *event) override; diff --git a/qrenderdoc/Windows/TextureViewer.cpp b/qrenderdoc/Windows/TextureViewer.cpp index 2a85819d1..65e2f4a40 100644 --- a/qrenderdoc/Windows/TextureViewer.cpp +++ b/qrenderdoc/Windows/TextureViewer.cpp @@ -119,9 +119,9 @@ BoundResource Following::GetBoundResource(ICaptureContext &ctx, int arrayIdx) if(Type == FollowType::OutputColour) { - auto outputs = GetOutputTargets(ctx); + rdcarray outputs = GetOutputTargets(ctx); - if(index < outputs.size()) + if(index < outputs.count()) ret = outputs[index]; } else if(Type == FollowType::OutputDepth) @@ -130,7 +130,7 @@ BoundResource Following::GetBoundResource(ICaptureContext &ctx, int arrayIdx) } else if(Type == FollowType::ReadWrite) { - auto rw = GetReadWriteResources(ctx); + rdcarray rw = GetReadWriteResources(ctx); ShaderBindpointMapping mapping = GetMapping(ctx); @@ -138,13 +138,14 @@ BoundResource Following::GetBoundResource(ICaptureContext &ctx, int arrayIdx) { BindpointMap &key = mapping.ReadWriteResources[index]; - if(rw.contains(key)) - ret = rw[key][arrayIdx]; + int residx = rw.indexOf(key); + if(residx >= 0) + ret = rw[residx].Resources[arrayIdx]; } } else if(Type == FollowType::ReadOnly) { - auto ro = GetReadOnlyResources(ctx); + rdcarray ro = GetReadOnlyResources(ctx); ShaderBindpointMapping mapping = GetMapping(ctx); @@ -152,15 +153,16 @@ BoundResource Following::GetBoundResource(ICaptureContext &ctx, int arrayIdx) { BindpointMap &key = mapping.ReadOnlyResources[index]; - if(ro.contains(key)) - ret = ro[key][arrayIdx]; + int residx = ro.indexOf(key); + if(residx >= 0) + ret = ro[residx].Resources[arrayIdx]; } } return ret; } -QVector Following::GetOutputTargets(ICaptureContext &ctx) +rdcarray Following::GetOutputTargets(ICaptureContext &ctx) { const DrawcallDescription *curDraw = ctx.CurDrawcall(); bool copy = false, clear = false, compute = false; @@ -176,7 +178,7 @@ QVector Following::GetOutputTargets(ICaptureContext &ctx) } else { - QVector ret = ctx.CurPipelineState().GetOutputTargets(); + rdcarray ret = ctx.CurPipelineState().GetOutputTargets(); if(ret.isEmpty() && curDraw != NULL && (curDraw->flags & DrawFlags::Present)) { @@ -205,15 +207,14 @@ BoundResource Following::GetDepthTarget(ICaptureContext &ctx) return ctx.CurPipelineState().GetDepthTarget(); } -QMap> Following::GetReadWriteResources(ICaptureContext &ctx, - ShaderStage stage) +rdcarray Following::GetReadWriteResources(ICaptureContext &ctx, ShaderStage stage) { bool copy = false, clear = false, compute = false; GetDrawContext(ctx, copy, clear, compute); if(copy || clear) { - return QMap>(); + return rdcarray(); } else if(compute) { @@ -221,7 +222,7 @@ QMap> Following::GetReadWriteResources(ICap if(stage == ShaderStage::Pixel || stage == ShaderStage::Compute) return ctx.CurPipelineState().GetReadWriteResources(ShaderStage::Compute); else - return QMap>(); + return rdcarray(); } else { @@ -229,13 +230,12 @@ QMap> Following::GetReadWriteResources(ICap } } -QMap> Following::GetReadWriteResources(ICaptureContext &ctx) +rdcarray Following::GetReadWriteResources(ICaptureContext &ctx) { return GetReadWriteResources(ctx, Stage); } -QMap> Following::GetReadOnlyResources(ICaptureContext &ctx, - ShaderStage stage) +rdcarray Following::GetReadOnlyResources(ICaptureContext &ctx, ShaderStage stage) { const DrawcallDescription *curDraw = ctx.CurDrawcall(); bool copy = false, clear = false, compute = false; @@ -243,11 +243,11 @@ QMap> Following::GetReadOnlyResources(ICapt if(copy || clear) { - QMap> ret; + rdcarray ret; // only return copy source for one stage if(copy && stage == ShaderStage::Pixel) - ret[BindpointMap(0, 0)] = {BoundResource(curDraw->copySource)}; + ret.push_back(BoundResourceArray(BindpointMap(0, 0), {BoundResource(curDraw->copySource)})); return ret; } @@ -257,7 +257,7 @@ QMap> Following::GetReadOnlyResources(ICapt if(stage == ShaderStage::Pixel || stage == ShaderStage::Compute) return ctx.CurPipelineState().GetReadOnlyResources(ShaderStage::Compute); else - return QMap>(); + return rdcarray(); } else { @@ -265,7 +265,7 @@ QMap> Following::GetReadOnlyResources(ICapt } } -QMap> Following::GetReadOnlyResources(ICaptureContext &ctx) +rdcarray Following::GetReadOnlyResources(ICaptureContext &ctx) { return GetReadOnlyResources(ctx, Stage); } @@ -363,7 +363,7 @@ public: { if(filter.isEmpty()) texs.push_back(t); - else if(m_Ctx.GetResourceName(t.ID).contains(filter, Qt::CaseInsensitive)) + else if(QString(m_Ctx.GetResourceName(t.ID)).contains(filter, Qt::CaseInsensitive)) texs.push_back(t); } } @@ -1917,7 +1917,7 @@ void TextureViewer::InitResourcePreview(ResourcePreview *prev, ResourceId id, Co void TextureViewer::InitStageResourcePreviews(ShaderStage stage, const rdcarray &resourceDetails, const rdcarray &mapping, - QMap> &ResList, + rdcarray &ResList, ThumbnailStrip *prevs, int &prevIndex, bool copy, bool rw) { @@ -1925,12 +1925,13 @@ void TextureViewer::InitStageResourcePreviews(ShaderStage stage, { const BindpointMap &key = mapping[idx]; - const QVector *resArray = NULL; + const rdcarray *resArray = NULL; - if(ResList.contains(key)) - resArray = &ResList[key]; + int residx = ResList.indexOf(key); + if(residx >= 0) + resArray = &ResList[residx].Resources; - int arrayLen = resArray != NULL ? resArray->size() : 1; + int arrayLen = resArray != NULL ? resArray->count() : 1; for(int arrayIdx = 0; arrayIdx < arrayLen; arrayIdx++) { @@ -2572,7 +2573,7 @@ void TextureViewer::OnEventChanged(uint32_t eventID) w->setWindowTitle(m_Ctx.GetResourceName(id)); } - QVector RTs = Following::GetOutputTargets(m_Ctx); + rdcarray RTs = Following::GetOutputTargets(m_Ctx); BoundResource Depth = Following::GetDepthTarget(m_Ctx); int outIndex = 0; @@ -2581,7 +2582,7 @@ void TextureViewer::OnEventChanged(uint32_t eventID) bool copy = false, clear = false, compute = false; Following::GetDrawContext(m_Ctx, copy, clear, compute); - for(int rt = 0; rt < RTs.size(); rt++) + for(int rt = 0; rt < RTs.count(); rt++) { ResourcePreview *prev; @@ -2635,8 +2636,8 @@ void TextureViewer::OnEventChanged(uint32_t eventID) { ShaderStage stage = stages[i]; - QMap> RWs = Following::GetReadWriteResources(m_Ctx, stage); - QMap> ROs = Following::GetReadOnlyResources(m_Ctx, stage); + rdcarray RWs = Following::GetReadWriteResources(m_Ctx, stage); + rdcarray ROs = Following::GetReadOnlyResources(m_Ctx, stage); const ShaderReflection *details = Following::GetReflection(m_Ctx, stage); const ShaderBindpointMapping &mapping = Following::GetMapping(m_Ctx, stage); @@ -3740,19 +3741,19 @@ void TextureViewer::on_customEdit_clicked() return; } - QStringMap files; - files[filename] = src; + rdcstrpairs files; + files.push_back(make_rdcpair(filename, src)); IShaderViewer *s = m_Ctx.EditShader( true, lit("main"), files, // Save Callback [this, key, filename, path](ICaptureContext *ctx, IShaderViewer *viewer, - const QStringMap &updatedfiles) { + const rdcstrpairs &updatedfiles) { { QFile fileHandle(path); if(fileHandle.open(QFile::WriteOnly | QIODevice::Truncate | QIODevice::Text)) { - fileHandle.write(updatedfiles[filename].toUtf8()); + fileHandle.write(updatedfiles[0].second.c_str()); fileHandle.close(); // watcher doesn't trigger on internal modifications diff --git a/qrenderdoc/Windows/TextureViewer.h b/qrenderdoc/Windows/TextureViewer.h index fe0293723..0e2c221b4 100644 --- a/qrenderdoc/Windows/TextureViewer.h +++ b/qrenderdoc/Windows/TextureViewer.h @@ -71,19 +71,17 @@ struct Following ResourceId GetResourceId(ICaptureContext &ctx); BoundResource GetBoundResource(ICaptureContext &ctx, int arrayIdx); - static QVector GetOutputTargets(ICaptureContext &ctx); + static rdcarray GetOutputTargets(ICaptureContext &ctx); static BoundResource GetDepthTarget(ICaptureContext &ctx); - QMap> GetReadWriteResources(ICaptureContext &ctx); + rdcarray GetReadWriteResources(ICaptureContext &ctx); - static QMap> GetReadWriteResources(ICaptureContext &ctx, - ShaderStage stage); + static rdcarray GetReadWriteResources(ICaptureContext &ctx, ShaderStage stage); - QMap> GetReadOnlyResources(ICaptureContext &ctx); + rdcarray GetReadOnlyResources(ICaptureContext &ctx); - static QMap> GetReadOnlyResources(ICaptureContext &ctx, - ShaderStage stage); + static rdcarray GetReadOnlyResources(ICaptureContext &ctx, ShaderStage stage); const ShaderReflection *GetReflection(ICaptureContext &ctx); static const ShaderReflection *GetReflection(ICaptureContext &ctx, ShaderStage stage); @@ -237,8 +235,8 @@ private: void InitStageResourcePreviews(ShaderStage stage, const rdcarray &resourceDetails, const rdcarray &mapping, - QMap> &ResList, - ThumbnailStrip *prevs, int &prevIndex, bool copy, bool rw); + rdcarray &ResList, ThumbnailStrip *prevs, + int &prevIndex, bool copy, bool rw); void AddResourceUsageEntry(QMenu &menu, uint32_t start, uint32_t end, ResourceUsage usage); void OpenResourceContextMenu(ResourceId id, const rdcarray &usage); diff --git a/qrenderdoc/Windows/TimelineBar.cpp b/qrenderdoc/Windows/TimelineBar.cpp index d2f3e11b0..07b6ef604 100644 --- a/qrenderdoc/Windows/TimelineBar.cpp +++ b/qrenderdoc/Windows/TimelineBar.cpp @@ -91,7 +91,7 @@ void TimelineBar::HighlightResourceUsage(ResourceId id) viewport()->update(); } -void TimelineBar::HighlightHistory(ResourceId id, const QList &history) +void TimelineBar::HighlightHistory(ResourceId id, const rdcarray &history) { m_ID = id; m_HistoryTarget = QString(); diff --git a/qrenderdoc/Windows/TimelineBar.h b/qrenderdoc/Windows/TimelineBar.h index 399b8728a..cf4ab521e 100644 --- a/qrenderdoc/Windows/TimelineBar.h +++ b/qrenderdoc/Windows/TimelineBar.h @@ -40,7 +40,7 @@ public: // IStatisticsViewer QWidget *Widget() override { return this; } void HighlightResourceUsage(ResourceId id) override; - void HighlightHistory(ResourceId id, const QList &history) override; + void HighlightHistory(ResourceId id, const rdcarray &history) override; // ICaptureViewer void OnCaptureLoaded() override; void OnCaptureClosed() override; diff --git a/renderdoc/api/replay/basic_types.h b/renderdoc/api/replay/basic_types.h index 83977beee..9f52b4674 100644 --- a/renderdoc/api/replay/basic_types.h +++ b/renderdoc/api/replay/basic_types.h @@ -167,6 +167,7 @@ public: const T *end() const { return elems ? elems + usedCount : NULL; } const T &front() const { return *elems; } const T &back() const { return *(elems + usedCount - 1); } + const T &at(size_t idx) const { return elems[idx]; } size_t size() const { return (size_t)usedCount; } size_t byteSize() const { return (size_t)usedCount * sizeof(T); } int32_t count() const { return (int32_t)usedCount; } @@ -395,6 +396,40 @@ public: // update new size setUsedCount(usedCount - (int32_t)count); } + + ///////////////////////////////////////////////////////////////// + // Qt style helper functions + + // erase & return an index + T takeAt(size_t offs) + { + T ret = elems[offs]; + erase(offs); + return ret; + } + + // find the first occurrence of an element + int32_t indexOf(const T &el, size_t first = 0, size_t last = ~0U) const + { + for(int32_t i = (int32_t)first; i < usedCount && (size_t)i < last; i++) + { + if(elems[i] == el) + return i; + } + + return -1; + } + + // return true if an element is found + bool contains(const T &el) const { return indexOf(el) != -1; } + // remove the first occurrence of an element + void removeOne(const T &el) + { + int idx = indexOf(el); + if(idx >= 0) + erase((size_t)idx); + } + ///////////////////////////////////////////////////////////////// // constructors that just forward to assign rdcarray(const T *in, size_t count) @@ -632,3 +667,6 @@ struct bytebuf : public rdcarray } #endif }; + +typedef rdcpair rdcstrpair; +typedef rdcarray rdcstrpairs; diff --git a/renderdoc/api/replay/shader_types.h b/renderdoc/api/replay/shader_types.h index 7accee5e9..b9ef26928 100644 --- a/renderdoc/api/replay/shader_types.h +++ b/renderdoc/api/replay/shader_types.h @@ -598,7 +598,7 @@ struct BindpointMap return bindset < o.bindset; return bind < o.bind; } - + bool operator==(const BindpointMap &o) const { return bindset == o.bindset && bind == o.bind; } DOCUMENT("The binding set."); int32_t bindset; DOCUMENT("The binding index."); diff --git a/renderdoc/api/replay/structured_data.h b/renderdoc/api/replay/structured_data.h index 6b609d667..feaade58e 100644 --- a/renderdoc/api/replay/structured_data.h +++ b/renderdoc/api/replay/structured_data.h @@ -352,7 +352,7 @@ struct SDObject DOCUMENT("Add a new child object by duplicating it."); inline void addChild(SDObject *child) { data.children.push_back(child->Duplicate()); } -#if defined(RENDERDOC_QT_COMPAT) && !defined(SWIG) +#if defined(RENDERDOC_QT_COMPAT) operator QVariant() const { switch(type.basetype) @@ -394,7 +394,7 @@ protected: DECLARE_REFLECTION_STRUCT(SDObject); -#if defined(RENDERDOC_QT_COMPAT) && !defined(SWIG) +#if defined(RENDERDOC_QT_COMPAT) inline SDObject *makeSDObject(const char *name, QVariant val) { SDObject *ret = new SDObject(name, "QVariant");