From ea4350f52fe8b0deeea438482c6017cbc4c40105 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 2 Apr 2015 17:38:13 +0100 Subject: [PATCH] Expose C++ interface via API headers, for C++ UI * Since the exported C functions just take an explicit 'this' parameter and call the corresponding function, we can just make it contractual via a virtual interface that the pointer can be dereferenced. --- renderdoc/api/replay/renderdoc_replay.h | 156 ++++++++++++++++++++++-- renderdoc/core/core.h | 2 + renderdoc/core/remote_access.cpp | 2 +- renderdoc/core/remote_replay.cpp | 2 +- renderdoc/replay/replay_renderer.cpp | 26 ++-- renderdoc/replay/replay_renderer.h | 7 +- renderdocui/Interop/ReplayRenderer.cs | 14 +-- 7 files changed, 175 insertions(+), 34 deletions(-) diff --git a/renderdoc/api/replay/renderdoc_replay.h b/renderdoc/api/replay/renderdoc_replay.h index 9c2e5d39e..31cff5c09 100644 --- a/renderdoc/api/replay/renderdoc_replay.h +++ b/renderdoc/api/replay/renderdoc_replay.h @@ -100,10 +100,38 @@ struct ResourceId #include "d3d11_pipestate.h" #include "gl_pipestate.h" +// for C++ expose the interface as a virtual interface +#ifdef __cplusplus + +struct IReplayOutput +{ + virtual bool SetOutputConfig(const OutputConfig &o) = 0; + virtual bool SetTextureDisplay(const TextureDisplay &o) = 0; + virtual bool SetMeshDisplay(const MeshDisplay &o) = 0; + + virtual bool ClearThumbnails() = 0; + virtual bool AddThumbnail(void *wnd, ResourceId texID) = 0; + + virtual bool Display() = 0; + + virtual bool SetPixelContext(void *wnd) = 0; + virtual bool SetPixelContextLocation(uint32_t x, uint32_t y) = 0; + virtual void DisablePixelContext() = 0; + + virtual bool PickPixel(ResourceId texID, bool customShader, + uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *val) = 0; +}; + +#endif + #ifdef RENDERDOC_EXPORTS -struct ReplayOutput; + struct ReplayOutput; #else -struct ReplayOutput { }; + #ifdef __cplusplus + typedef IReplayOutput ReplayOutput; + #else + struct ReplayOutput { }; + #endif #endif extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetOutputConfig(ReplayOutput *output, const OutputConfig &o); @@ -123,10 +151,74 @@ extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_PickPixel(ReplayOutput uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *val); extern "C" RENDERDOC_API uint32_t RENDERDOC_CC ReplayOutput_PickVertex(ReplayOutput *output, uint32_t frameID, uint32_t eventID, uint32_t x, uint32_t y); +// for C++ expose the interface as a virtual interface +#ifdef __cplusplus + +struct IReplayRenderer +{ + virtual APIProperties GetAPIProperties() = 0; + + virtual ReplayOutput* CreateOutput(void *handle) = 0; + virtual void Shutdown() = 0; + virtual void ShutdownOutput(ReplayOutput *output) = 0; + + virtual bool HasCallstacks() = 0; + virtual bool InitResolver() = 0; + + virtual bool SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv) = 0; + virtual bool SetFrameEvent(uint32_t frameID, uint32_t eventID) = 0; + virtual bool GetD3D11PipelineState(D3D11PipelineState *state) = 0; + virtual bool GetGLPipelineState(GLPipelineState *state) = 0; + + virtual ResourceId BuildCustomShader(const char *entry, const char *source, const uint32_t compileFlags, ShaderStageType type, rdctype::str *errors) = 0; + virtual bool FreeCustomShader(ResourceId id) = 0; + + virtual ResourceId BuildTargetShader(const char *entry, const char *source, const uint32_t compileFlags, ShaderStageType type, rdctype::str *errors) = 0; + virtual bool ReplaceResource(ResourceId from, ResourceId to) = 0; + virtual bool RemoveReplacement(ResourceId id) = 0; + virtual bool FreeTargetResource(ResourceId id) = 0; + + virtual bool GetFrameInfo(rdctype::array *frame) = 0; + virtual bool GetDrawcalls(uint32_t frameID, rdctype::array *draws) = 0; + virtual bool FetchCounters(uint32_t frameID, uint32_t minEventID, uint32_t maxEventID, uint32_t *counters, uint32_t numCounters, rdctype::array *results) = 0; + virtual bool EnumerateCounters(rdctype::array *counters) = 0; + virtual bool DescribeCounter(uint32_t counterID, CounterDescription *desc) = 0; + virtual bool GetTextures(rdctype::array *texs) = 0; + virtual bool GetBuffers(rdctype::array *bufs) = 0; + virtual bool GetResolve(uint64_t *callstack, uint32_t callstackLen, rdctype::array *trace) = 0; + virtual ShaderReflection* GetShaderDetails(ResourceId shader) = 0; + virtual bool GetDebugMessages(rdctype::array *msgs) = 0; + + virtual bool PixelHistory(ResourceId target, uint32_t x, uint32_t y, uint32_t sampleIdx, rdctype::array *history) = 0; + virtual bool DebugVertex(uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset, ShaderDebugTrace *trace) = 0; + virtual bool DebugPixel(uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive, ShaderDebugTrace *trace) = 0; + virtual bool DebugThread(uint32_t groupid[3], uint32_t threadid[3], ShaderDebugTrace *trace) = 0; + + virtual bool GetUsage(ResourceId id, rdctype::array *usage) = 0; + + virtual bool GetCBufferVariableContents(ResourceId shader, uint32_t cbufslot, ResourceId buffer, uint32_t offs, rdctype::array *vars) = 0; + + virtual bool SaveTexture(const TextureSave &saveData, const char *path) = 0; + + virtual bool GetPostVSData(uint32_t instID, MeshDataStage stage, MeshFormat *data) = 0; + + virtual bool GetMinMax(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *minval, PixelValue *maxval) = 0; + virtual bool GetHistogram(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], rdctype::array *histogram) = 0; + + virtual bool GetBufferData(ResourceId buff, uint32_t offset, uint32_t len, rdctype::array *data) = 0; + virtual bool GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, rdctype::array *data) = 0; +}; + +#endif + #ifdef RENDERDOC_EXPORTS -struct ReplayRenderer; + struct ReplayRenderer; #else -struct ReplayRenderer { }; + #ifdef __cplusplus + typedef IReplayRenderer ReplayRenderer; + #else + struct ReplayRenderer { }; + #endif #endif extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_GetAPIProperties(ReplayRenderer *rend, APIProperties *props); @@ -143,10 +235,10 @@ extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_SetFrameEvent(Replay extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetD3D11PipelineState(ReplayRenderer *rend, D3D11PipelineState *state); extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetGLPipelineState(ReplayRenderer *rend, GLPipelineState *state); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_BuildCustomShader(ReplayRenderer *rend, const char *entry, const char *source, const uint32_t compileFlags, ShaderStageType type, ResourceId *shaderID, rdctype::str *errors); +extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_BuildCustomShader(ReplayRenderer *rend, const char *entry, const char *source, const uint32_t compileFlags, ShaderStageType type, ResourceId *shaderID, rdctype::str *errors); extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_FreeCustomShader(ReplayRenderer *rend, ResourceId id); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_BuildTargetShader(ReplayRenderer *rend, const char *entry, const char *source, const uint32_t compileFlags, ShaderStageType type, ResourceId *shaderID, rdctype::str *errors); +extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_BuildTargetShader(ReplayRenderer *rend, const char *entry, const char *source, const uint32_t compileFlags, ShaderStageType type, ResourceId *shaderID, rdctype::str *errors); extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_ReplaceResource(ReplayRenderer *rend, ResourceId from, ResourceId to); extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_RemoveReplacement(ReplayRenderer *rend, ResourceId id); extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_FreeTargetResource(ReplayRenderer *rend, ResourceId id); @@ -181,10 +273,35 @@ extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetHistogram(ReplayR extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetBufferData(ReplayRenderer *rend, ResourceId buff, uint32_t offset, uint32_t len, rdctype::array *data); extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetTextureData(ReplayRenderer *rend, ResourceId tex, uint32_t arrayIdx, uint32_t mip, rdctype::array *data); +// for C++ expose the interface as a virtual interface +#ifdef __cplusplus + +struct IRemoteAccess +{ + virtual void Shutdown() = 0; + + virtual const char* GetTarget() = 0; + virtual const char* GetAPI() = 0; + virtual uint32_t GetPID() = 0; + virtual const char* GetBusyClient() = 0; + + virtual void TriggerCapture() = 0; + virtual void QueueCapture(uint32_t frameNumber) = 0; + virtual void CopyCapture(uint32_t remoteID, const char *localpath) = 0; + + virtual void ReceiveMessage(RemoteMessage *msg) = 0; +}; + +#endif + #ifdef RENDERDOC_EXPORTS -struct RemoteAccess; + struct RemoteAccess; #else -struct RemoteAccess { }; + #ifdef __cplusplus + typedef IRemoteAccess RemoteAccess; + #else + struct RemoteAccess { }; + #endif #endif extern "C" RENDERDOC_API void RENDERDOC_CC RemoteAccess_Shutdown(RemoteAccess *access); @@ -200,10 +317,29 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RemoteAccess_CopyCapture(RemoteAccess extern "C" RENDERDOC_API void RENDERDOC_CC RemoteAccess_ReceiveMessage(RemoteAccess *access, RemoteMessage *msg); +// for C++ expose the interface as a virtual interface +#ifdef __cplusplus + +struct IRemoteRenderer +{ + virtual void Shutdown() = 0; + + virtual bool LocalProxies(rdctype::array *out) = 0; + virtual bool RemoteSupportedReplays(rdctype::array *out) = 0; + + virtual ReplayCreateStatus CreateProxyRenderer(uint32_t proxyid, const char *logfile, float *progress, ReplayRenderer **rend) = 0; +}; + +#endif + #ifdef RENDERDOC_EXPORTS -struct RemoteRenderer; + struct RemoteRenderer; #else -struct RemoteRenderer { }; + #ifdef __cplusplus + typedef IRemoteRenderer RemoteRenderer; + #else + struct RemoteRenderer { }; + #endif #endif extern "C" RENDERDOC_API void RENDERDOC_CC RemoteRenderer_Shutdown(RemoteRenderer *remote); diff --git a/renderdoc/core/core.h b/renderdoc/core/core.h index 26832ca5a..23e6c22c8 100644 --- a/renderdoc/core/core.h +++ b/renderdoc/core/core.h @@ -110,6 +110,8 @@ enum RDCDriver RDC_Custom9, }; +typedef uint32_t bool32; + namespace DXBC { class DXBCFile; } namespace Callstack { class StackResolver; } diff --git a/renderdoc/core/remote_access.cpp b/renderdoc/core/remote_access.cpp index ac18a9c85..e7c71df75 100644 --- a/renderdoc/core/remote_access.cpp +++ b/renderdoc/core/remote_access.cpp @@ -351,7 +351,7 @@ void RenderDoc::RemoteAccessServerThread(void *s) Threading::ReleaseModuleExitThread(); } -struct RemoteAccess +struct RemoteAccess : public IRemoteAccess { public: RemoteAccess(Network::Socket *sock, string clientName, bool forceConnection, bool localhost) diff --git a/renderdoc/core/remote_replay.cpp b/renderdoc/core/remote_replay.cpp index a0b42b1a5..49f498b2e 100644 --- a/renderdoc/core/remote_replay.cpp +++ b/renderdoc/core/remote_replay.cpp @@ -227,7 +227,7 @@ void RenderDoc::BecomeReplayHost(volatile bool32 &killReplay) } } -struct RemoteRenderer +struct RemoteRenderer : public IRemoteRenderer { public: RemoteRenderer(Network::Socket *sock) diff --git a/renderdoc/replay/replay_renderer.cpp b/renderdoc/replay/replay_renderer.cpp index 56309a180..87f2cd912 100644 --- a/renderdoc/replay/replay_renderer.cpp +++ b/renderdoc/replay/replay_renderer.cpp @@ -1268,6 +1268,16 @@ ReplayOutput *ReplayRenderer::CreateOutput(void *wndhandle) return out; } +void ReplayRenderer::ShutdownOutput(ReplayOutput *output) +{ + RDCUNIMPLEMENTED("Shutting down individual outputs"); +} + +void ReplayRenderer::Shutdown() +{ + delete this; +} + ResourceId ReplayRenderer::BuildTargetShader(const char *entry, const char *source, const uint32_t compileFlags, ShaderStageType type, rdctype::str *errors) { ResourceId id; @@ -1509,9 +1519,9 @@ extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_GetAPIProperties(Repla extern "C" RENDERDOC_API ReplayOutput* RENDERDOC_CC ReplayRenderer_CreateOutput(ReplayRenderer *rend, void *handle) { return rend->CreateOutput(handle); } extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_Shutdown(ReplayRenderer *rend) -{ delete rend; } +{ rend->Shutdown(); } extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_ShutdownOutput(ReplayRenderer *rend, ReplayOutput *output) -{ RDCUNIMPLEMENTED("destroying individual outputs"); } +{ rend->ShutdownOutput(output); } extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_HasCallstacks(ReplayRenderer *rend) { return rend->HasCallstacks(); } @@ -1527,24 +1537,20 @@ extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetD3D11PipelineStat extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetGLPipelineState(ReplayRenderer *rend, GLPipelineState *state) { return rend->GetGLPipelineState(state); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_BuildCustomShader(ReplayRenderer *rend, const char *entry, const char *source, const uint32_t compileFlags, ShaderStageType type, ResourceId *shaderID, rdctype::str *errors) +extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_BuildCustomShader(ReplayRenderer *rend, const char *entry, const char *source, const uint32_t compileFlags, ShaderStageType type, ResourceId *shaderID, rdctype::str *errors) { - if(shaderID == NULL) return false; + if(shaderID == NULL) return; *shaderID = rend->BuildCustomShader(entry, source, compileFlags, type, errors); - - return (*shaderID != ResourceId()); } extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_FreeCustomShader(ReplayRenderer *rend, ResourceId id) { return rend->FreeCustomShader(id); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_BuildTargetShader(ReplayRenderer *rend, const char *entry, const char *source, const uint32_t compileFlags, ShaderStageType type, ResourceId *shaderID, rdctype::str *errors) +extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_BuildTargetShader(ReplayRenderer *rend, const char *entry, const char *source, const uint32_t compileFlags, ShaderStageType type, ResourceId *shaderID, rdctype::str *errors) { - if(shaderID == NULL) return false; + if(shaderID == NULL) return; *shaderID = rend->BuildTargetShader(entry, source, compileFlags, type, errors); - - return (*shaderID != ResourceId()); } extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_ReplaceResource(ReplayRenderer *rend, ResourceId from, ResourceId to) { return rend->ReplaceResource(from, to); } diff --git a/renderdoc/replay/replay_renderer.h b/renderdoc/replay/replay_renderer.h index c873cabc1..8d1810299 100644 --- a/renderdoc/replay/replay_renderer.h +++ b/renderdoc/replay/replay_renderer.h @@ -37,7 +37,7 @@ struct ReplayRenderer; -struct ReplayOutput +struct ReplayOutput : public IReplayOutput { public: bool SetOutputConfig(const OutputConfig &o); @@ -123,7 +123,7 @@ private: friend struct ReplayRenderer; }; -struct ReplayRenderer +struct ReplayRenderer : public IReplayRenderer { public: ReplayRenderer(); @@ -185,6 +185,9 @@ struct ReplayRenderer bool GetCBufferVariableContents(ResourceId shader, uint32_t cbufslot, ResourceId buffer, uint32_t offs, rdctype::array *vars); ReplayOutput *CreateOutput(void *handle); + + void ShutdownOutput(ReplayOutput *output); + void Shutdown(); private: ReplayCreateStatus PostCreateInit(IReplayDriver *device); diff --git a/renderdocui/Interop/ReplayRenderer.cs b/renderdocui/Interop/ReplayRenderer.cs index 8f7f59814..d1c62d844 100644 --- a/renderdocui/Interop/ReplayRenderer.cs +++ b/renderdocui/Interop/ReplayRenderer.cs @@ -200,12 +200,12 @@ namespace renderdoc private static extern bool ReplayRenderer_GetGLPipelineState(IntPtr real, IntPtr mem); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] - private static extern bool ReplayRenderer_BuildCustomShader(IntPtr real, IntPtr entry, IntPtr source, UInt32 compileFlags, ShaderStageType type, ref ResourceId shaderID, IntPtr errorMem); + private static extern void ReplayRenderer_BuildCustomShader(IntPtr real, IntPtr entry, IntPtr source, UInt32 compileFlags, ShaderStageType type, ref ResourceId shaderID, IntPtr errorMem); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] private static extern bool ReplayRenderer_FreeCustomShader(IntPtr real, ResourceId id); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] - private static extern bool ReplayRenderer_BuildTargetShader(IntPtr real, IntPtr entry, IntPtr source, UInt32 compileFlags, ShaderStageType type, ref ResourceId shaderID, IntPtr errorMem); + private static extern void ReplayRenderer_BuildTargetShader(IntPtr real, IntPtr entry, IntPtr source, UInt32 compileFlags, ShaderStageType type, ref ResourceId shaderID, IntPtr errorMem); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] private static extern bool ReplayRenderer_ReplaceResource(IntPtr real, ResourceId from, ResourceId to); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] @@ -353,14 +353,11 @@ namespace renderdoc IntPtr entry_mem = CustomMarshal.MakeUTF8String(entry); IntPtr source_mem = CustomMarshal.MakeUTF8String(source); - bool success = ReplayRenderer_BuildCustomShader(m_Real, entry_mem, source_mem, compileFlags, type, ref ret, mem); + ReplayRenderer_BuildCustomShader(m_Real, entry_mem, source_mem, compileFlags, type, ref ret, mem); CustomMarshal.Free(entry_mem); CustomMarshal.Free(source_mem); - if (!success) - ret = ResourceId.Null; - errors = CustomMarshal.TemplatedArrayToString(mem, true); CustomMarshal.Free(mem); @@ -380,14 +377,11 @@ namespace renderdoc IntPtr entry_mem = CustomMarshal.MakeUTF8String(entry); IntPtr source_mem = CustomMarshal.MakeUTF8String(source); - bool success = ReplayRenderer_BuildTargetShader(m_Real, entry_mem, source_mem, compileFlags, type, ref ret, mem); + ReplayRenderer_BuildTargetShader(m_Real, entry_mem, source_mem, compileFlags, type, ref ret, mem); CustomMarshal.Free(entry_mem); CustomMarshal.Free(source_mem); - if (!success) - ret = ResourceId.Null; - errors = CustomMarshal.TemplatedArrayToString(mem, true); CustomMarshal.Free(mem);