mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-08 16:50:44 +00:00
Report supported windowing systems from replay, and choose which to use
* This is primarily for vulkan, which supports either xlib or xcb (and not necessarily both). GL still only supports xlib, windows and android only support one system regardless of API. * This should also support xlib again for fetching keystates etc.
This commit is contained in:
+2
-2
@@ -32,13 +32,13 @@ Requirements are linking against -lX11 and -lGL. For qrenderdoc you need qt5 alo
|
||||
This is the apt-get line you'd need to install the requirements on Ubuntu 14.04:
|
||||
|
||||
```
|
||||
sudo apt-get install libx11-dev mesa-common-dev libgl1-mesa-dev qt5-default libqt5x11extras5-dev libxcb-keysyms1-dev cmake
|
||||
sudo apt-get install libx11-dev libx11-xcb-dev mesa-common-dev libgl1-mesa-dev qt5-default libqt5x11extras5-dev libxcb-keysyms1-dev cmake
|
||||
```
|
||||
|
||||
For Archlinux (as of 2016.02.01) you'll need:
|
||||
|
||||
```
|
||||
sudo pacman -S libx11 xcb-util-keysyms mesa mesa-libgl qt5-base qt5-x11extras cmake
|
||||
sudo pacman -S libx11 libx11-xcb xcb-util-keysyms mesa mesa-libgl qt5-base qt5-x11extras cmake
|
||||
```
|
||||
|
||||
If you know the required packages for another distribution, please share (or pull request this file!)
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
#if defined(__linux__)
|
||||
#define RENDERDOC_WINDOWING_XLIB 1
|
||||
#define RENDERDOC_WINDOWING_XCB 1
|
||||
#endif
|
||||
|
||||
#include "TextureViewer.h"
|
||||
#include "Code/Core.h"
|
||||
#include "FlowLayout.h"
|
||||
@@ -5,6 +10,7 @@
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <GL/glx.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <xcb/xcb.h>
|
||||
#include <QX11Info>
|
||||
#endif
|
||||
@@ -162,19 +168,54 @@ void TextureViewer::on_render_clicked(QMouseEvent *e)
|
||||
void TextureViewer::OnLogfileLoaded()
|
||||
{
|
||||
#if defined(WIN32)
|
||||
HWND wnd = (HWND)ui->render->winId();
|
||||
#elif defined(__linux__)
|
||||
xcb_connection_t *display = QX11Info::connection();
|
||||
xcb_window_t window = (xcb_window_t)ui->render->winId();
|
||||
|
||||
void *connectionScreenWindow[3] = {(void *)display, (void *)0, (void *)(uintptr_t)window};
|
||||
void *wnd = connectionScreenWindow;
|
||||
WindowingSystem system = eWindowingSystem_Win32;
|
||||
HWND wnd = (HWND)ui->render->winId();
|
||||
|
||||
#elif defined(__linux__)
|
||||
|
||||
XCBWindowData xcb = {
|
||||
QX11Info::connection(), (xcb_window_t)ui->render->winId(),
|
||||
};
|
||||
|
||||
XlibWindowData xlib = {QX11Info::display(), (Drawable)ui->render->winId()};
|
||||
|
||||
rdctype::array<WindowingSystem> systems;
|
||||
m_Core->Renderer()->BlockInvoke(
|
||||
[&systems](IReplayRenderer *r) { r->GetSupportedWindowSystems(&systems); });
|
||||
|
||||
WindowingSystem system = eWindowingSystem_Unknown;
|
||||
void *wnd = NULL;
|
||||
|
||||
// prefer XCB
|
||||
for(int32_t i = 0; i < systems.count; i++)
|
||||
{
|
||||
if(systems[i] == eWindowingSystem_XCB)
|
||||
{
|
||||
system = eWindowingSystem_XCB;
|
||||
wnd = &xcb;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(int32_t i = 0; wnd == NULL && i < systems.count; i++)
|
||||
{
|
||||
if(systems[i] == eWindowingSystem_Xlib)
|
||||
{
|
||||
system = eWindowingSystem_Xlib;
|
||||
wnd = &xlib;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#error "Unknown platform"
|
||||
|
||||
#endif
|
||||
|
||||
m_Core->Renderer()->BlockInvoke([wnd, this](IReplayRenderer *r) {
|
||||
m_Output = r->CreateOutput(wnd, eOutputType_TexDisplay);
|
||||
m_Core->Renderer()->BlockInvoke([system, wnd, this](IReplayRenderer *r) {
|
||||
m_Output = r->CreateOutput(system, wnd, eOutputType_TexDisplay);
|
||||
ui->render->SetOutput(m_Output);
|
||||
|
||||
OutputConfig c = {eOutputType_TexDisplay};
|
||||
|
||||
@@ -55,6 +55,57 @@ typedef uint32_t bool32;
|
||||
|
||||
#endif
|
||||
|
||||
// windowing structures
|
||||
|
||||
#if defined(RENDERDOC_PLATFORM_WIN32)
|
||||
|
||||
// Win32 uses HWND
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(RENDERDOC_WINDOWING_XLIB)
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#undef None
|
||||
|
||||
struct XlibWindowData
|
||||
{
|
||||
Display *display;
|
||||
Drawable window;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(RENDERDOC_WINDOWING_XCB)
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
#undef None
|
||||
|
||||
struct XCBWindowData
|
||||
{
|
||||
xcb_connection_t *connection;
|
||||
xcb_window_t window;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(RENDERDOC_PLATFORM_ANDROID)
|
||||
|
||||
// android uses ANativeWindow*
|
||||
|
||||
#endif
|
||||
|
||||
enum WindowingSystem
|
||||
{
|
||||
eWindowingSystem_Unknown,
|
||||
eWindowingSystem_Win32,
|
||||
eWindowingSystem_Xlib,
|
||||
eWindowingSystem_XCB,
|
||||
eWindowingSystem_Android,
|
||||
};
|
||||
|
||||
// needs to be declared up here for reference in basic_types
|
||||
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_FreeArrayMem(const void *mem);
|
||||
@@ -101,11 +152,12 @@ struct IReplayOutput
|
||||
virtual bool SetMeshDisplay(const MeshDisplay &o) = 0;
|
||||
|
||||
virtual bool ClearThumbnails() = 0;
|
||||
virtual bool AddThumbnail(void *wnd, ResourceId texID, FormatComponentType typeHint) = 0;
|
||||
virtual bool AddThumbnail(WindowingSystem system, void *data, ResourceId texID,
|
||||
FormatComponentType typeHint) = 0;
|
||||
|
||||
virtual bool Display() = 0;
|
||||
|
||||
virtual bool SetPixelContext(void *wnd) = 0;
|
||||
virtual bool SetPixelContext(WindowingSystem system, void *data) = 0;
|
||||
virtual bool SetPixelContextLocation(uint32_t x, uint32_t y) = 0;
|
||||
virtual void DisablePixelContext() = 0;
|
||||
|
||||
@@ -136,13 +188,15 @@ extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetMeshDisplay(ReplayO
|
||||
|
||||
extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_ClearThumbnails(ReplayOutput *output);
|
||||
extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_AddThumbnail(ReplayOutput *output,
|
||||
void *wnd, ResourceId texID,
|
||||
WindowingSystem system,
|
||||
void *data, ResourceId texID,
|
||||
FormatComponentType typeHint);
|
||||
|
||||
extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_Display(ReplayOutput *output);
|
||||
|
||||
extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetPixelContext(ReplayOutput *output,
|
||||
void *wnd);
|
||||
WindowingSystem system,
|
||||
void *data);
|
||||
extern "C" RENDERDOC_API bool32 RENDERDOC_CC
|
||||
ReplayOutput_SetPixelContextLocation(ReplayOutput *output, uint32_t x, uint32_t y);
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC ReplayOutput_DisablePixelContext(ReplayOutput *output);
|
||||
@@ -164,7 +218,9 @@ struct IReplayRenderer
|
||||
{
|
||||
virtual APIProperties GetAPIProperties() = 0;
|
||||
|
||||
virtual ReplayOutput *CreateOutput(void *handle, OutputType type) = 0;
|
||||
virtual void GetSupportedWindowSystems(rdctype::array<WindowingSystem> *systems) = 0;
|
||||
|
||||
virtual ReplayOutput *CreateOutput(WindowingSystem system, void *data, OutputType type) = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
virtual void ShutdownOutput(ReplayOutput *output) = 0;
|
||||
|
||||
@@ -251,9 +307,11 @@ struct ReplayRenderer
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_GetAPIProperties(ReplayRenderer *rend,
|
||||
APIProperties *props);
|
||||
|
||||
extern "C" RENDERDOC_API ReplayOutput *RENDERDOC_CC ReplayRenderer_CreateOutput(ReplayRenderer *rend,
|
||||
void *handle,
|
||||
OutputType type);
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_GetSupportedWindowSystems(
|
||||
ReplayRenderer *rend, rdctype::array<WindowingSystem> *systems);
|
||||
|
||||
extern "C" RENDERDOC_API ReplayOutput *RENDERDOC_CC ReplayRenderer_CreateOutput(
|
||||
ReplayRenderer *rend, WindowingSystem system, void *data, OutputType type);
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_Shutdown(ReplayRenderer *rend);
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_ShutdownOutput(ReplayRenderer *rend,
|
||||
ReplayOutput *output);
|
||||
|
||||
@@ -73,6 +73,25 @@ string ToStrHelper<false, RDCDriver>::Get(const RDCDriver &el)
|
||||
return tostrBuf;
|
||||
}
|
||||
|
||||
template <>
|
||||
string ToStrHelper<false, WindowingSystem>::Get(const WindowingSystem &el)
|
||||
{
|
||||
switch(el)
|
||||
{
|
||||
case eWindowingSystem_Unknown: return "Unknown";
|
||||
case eWindowingSystem_Win32: return "Win32";
|
||||
case eWindowingSystem_Xlib: return "Xlib";
|
||||
case eWindowingSystem_XCB: return "XCB";
|
||||
case eWindowingSystem_Android: return "Android";
|
||||
default: break;
|
||||
}
|
||||
|
||||
char tostrBuf[256] = {0};
|
||||
StringFormat::snprintf(tostrBuf, 255, "WindowingSystem<%d>", el);
|
||||
|
||||
return tostrBuf;
|
||||
}
|
||||
|
||||
template <>
|
||||
string ToStrHelper<false, RENDERDOC_InputButton>::Get(const RENDERDOC_InputButton &el)
|
||||
{
|
||||
|
||||
@@ -69,7 +69,14 @@ public:
|
||||
bool IsRemoteProxy() { return true; }
|
||||
void Shutdown() { delete this; }
|
||||
// pass through necessary operations to proxy
|
||||
uint64_t MakeOutputWindow(void *w, bool depth) { return m_Proxy->MakeOutputWindow(w, depth); }
|
||||
vector<WindowingSystem> GetSupportedWindowSystems()
|
||||
{
|
||||
return m_Proxy->GetSupportedWindowSystems();
|
||||
}
|
||||
uint64_t MakeOutputWindow(WindowingSystem system, void *data, bool depth)
|
||||
{
|
||||
return m_Proxy->MakeOutputWindow(system, data, depth);
|
||||
}
|
||||
void DestroyOutputWindow(uint64_t id) { m_Proxy->DestroyOutputWindow(id); }
|
||||
bool CheckResizeOutputWindow(uint64_t id) { return m_Proxy->CheckResizeOutputWindow(id); }
|
||||
void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h)
|
||||
|
||||
@@ -114,10 +114,16 @@ public:
|
||||
bool IsRemoteProxy() { return !m_ReplayHost; }
|
||||
void Shutdown() { delete this; }
|
||||
void ReadLogInitialisation() {}
|
||||
uint64_t MakeOutputWindow(void *w, bool depth)
|
||||
vector<WindowingSystem> GetSupportedWindowSystems()
|
||||
{
|
||||
if(m_Proxy)
|
||||
return m_Proxy->MakeOutputWindow(w, depth);
|
||||
return m_Proxy->GetSupportedWindowSystems();
|
||||
return vector<WindowingSystem>();
|
||||
}
|
||||
uint64_t MakeOutputWindow(WindowingSystem system, void *data, bool depth)
|
||||
{
|
||||
if(m_Proxy)
|
||||
return m_Proxy->MakeOutputWindow(system, data, depth);
|
||||
return 0;
|
||||
}
|
||||
void DestroyOutputWindow(uint64_t id)
|
||||
|
||||
@@ -1631,10 +1631,12 @@ void D3D11DebugManager::OutputWindow::MakeDSV()
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t D3D11DebugManager::MakeOutputWindow(void *w, bool depth)
|
||||
uint64_t D3D11DebugManager::MakeOutputWindow(WindowingSystem system, void *data, bool depth)
|
||||
{
|
||||
RDCASSERT(system == eWindowingSystem_Win32, system);
|
||||
|
||||
OutputWindow outw;
|
||||
outw.wnd = (HWND)w;
|
||||
outw.wnd = (HWND)data;
|
||||
outw.dev = m_WrappedDevice;
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC swapDesc;
|
||||
|
||||
@@ -101,7 +101,7 @@ public:
|
||||
D3D11DebugManager(WrappedID3D11Device *wrapper);
|
||||
~D3D11DebugManager();
|
||||
|
||||
uint64_t MakeOutputWindow(void *w, bool depth);
|
||||
uint64_t MakeOutputWindow(WindowingSystem system, void *data, bool depth);
|
||||
void DestroyOutputWindow(uint64_t id);
|
||||
bool CheckResizeOutputWindow(uint64_t id);
|
||||
void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h);
|
||||
|
||||
@@ -1347,9 +1347,9 @@ vector<uint32_t> D3D11Replay::GetPassEvents(uint32_t eventID)
|
||||
return passEvents;
|
||||
}
|
||||
|
||||
uint64_t D3D11Replay::MakeOutputWindow(void *w, bool depth)
|
||||
uint64_t D3D11Replay::MakeOutputWindow(WindowingSystem system, void *data, bool depth)
|
||||
{
|
||||
return m_pDevice->GetDebugManager()->MakeOutputWindow(w, depth);
|
||||
return m_pDevice->GetDebugManager()->MakeOutputWindow(system, data, depth);
|
||||
}
|
||||
|
||||
void D3D11Replay::DestroyOutputWindow(uint64_t id)
|
||||
|
||||
@@ -75,7 +75,14 @@ public:
|
||||
|
||||
vector<uint32_t> GetPassEvents(uint32_t eventID);
|
||||
|
||||
uint64_t MakeOutputWindow(void *w, bool depth);
|
||||
vector<WindowingSystem> GetSupportedWindowSystems()
|
||||
{
|
||||
vector<WindowingSystem> ret;
|
||||
ret.push_back(eWindowingSystem_Win32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t MakeOutputWindow(WindowingSystem system, void *data, bool depth);
|
||||
void DestroyOutputWindow(uint64_t id);
|
||||
bool CheckResizeOutputWindow(uint64_t id);
|
||||
void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h);
|
||||
|
||||
@@ -599,10 +599,12 @@ void D3D12DebugManager::OutputWindow::MakeDSV()
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t D3D12DebugManager::MakeOutputWindow(void *w, bool depth)
|
||||
uint64_t D3D12DebugManager::MakeOutputWindow(WindowingSystem system, void *data, bool depth)
|
||||
{
|
||||
RDCASSERT(system == eWindowingSystem_Win32, system);
|
||||
|
||||
OutputWindow outw;
|
||||
outw.wnd = (HWND)w;
|
||||
outw.wnd = (HWND)data;
|
||||
outw.dev = m_WrappedDevice;
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC swapDesc;
|
||||
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
D3D12DebugManager(WrappedID3D12Device *wrapper);
|
||||
~D3D12DebugManager();
|
||||
|
||||
uint64_t MakeOutputWindow(void *w, bool depth);
|
||||
uint64_t MakeOutputWindow(WindowingSystem system, void *data, bool depth);
|
||||
void DestroyOutputWindow(uint64_t id);
|
||||
bool CheckResizeOutputWindow(uint64_t id);
|
||||
void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h);
|
||||
|
||||
@@ -239,9 +239,9 @@ bool D3D12Replay::RenderTexture(TextureDisplay cfg)
|
||||
return m_pDevice->GetDebugManager()->RenderTexture(cfg, true);
|
||||
}
|
||||
|
||||
uint64_t D3D12Replay::MakeOutputWindow(void *w, bool depth)
|
||||
uint64_t D3D12Replay::MakeOutputWindow(WindowingSystem system, void *data, bool depth)
|
||||
{
|
||||
return m_pDevice->GetDebugManager()->MakeOutputWindow(w, depth);
|
||||
return m_pDevice->GetDebugManager()->MakeOutputWindow(system, data, depth);
|
||||
}
|
||||
|
||||
void D3D12Replay::DestroyOutputWindow(uint64_t id)
|
||||
|
||||
@@ -70,7 +70,14 @@ public:
|
||||
|
||||
vector<uint32_t> GetPassEvents(uint32_t eventID);
|
||||
|
||||
uint64_t MakeOutputWindow(void *w, bool depth);
|
||||
vector<WindowingSystem> GetSupportedWindowSystems()
|
||||
{
|
||||
vector<WindowingSystem> ret;
|
||||
ret.push_back(eWindowingSystem_Win32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t MakeOutputWindow(WindowingSystem system, void *data, bool depth);
|
||||
void DestroyOutputWindow(uint64_t id);
|
||||
bool CheckResizeOutputWindow(uint64_t id);
|
||||
void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h);
|
||||
|
||||
@@ -219,7 +219,7 @@ void GLReplay::InitDebugData()
|
||||
RenderDoc::Inst().SetProgress(DebugManagerInit, 0.0f);
|
||||
|
||||
{
|
||||
uint64_t id = MakeOutputWindow(NULL, true);
|
||||
uint64_t id = MakeOutputWindow(eWindowingSystem_Unknown, NULL, true);
|
||||
|
||||
m_DebugID = id;
|
||||
m_DebugCtx = &m_OutputWindows[id];
|
||||
|
||||
@@ -115,7 +115,19 @@ public:
|
||||
|
||||
vector<uint32_t> GetPassEvents(uint32_t eventID);
|
||||
|
||||
uint64_t MakeOutputWindow(void *w, bool depth);
|
||||
vector<WindowingSystem> GetSupportedWindowSystems()
|
||||
{
|
||||
vector<WindowingSystem> ret;
|
||||
// only Xlib supported for GLX. We can't report XCB here since we need
|
||||
// the Display, and that can't be obtained from XCB. The application is
|
||||
// free to use XCB internally but it would have to create a hybrid and
|
||||
// initialise XCB out of Xlib, to be able to provide the display and
|
||||
// drawable to us.
|
||||
ret.push_back(eWindowingSystem_Xlib);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t MakeOutputWindow(WindowingSystem system, void *data, bool depth);
|
||||
void DestroyOutputWindow(uint64_t id);
|
||||
bool CheckResizeOutputWindow(uint64_t id);
|
||||
void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h);
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#define RENDERDOC_WINDOWING_XLIB 1
|
||||
|
||||
#include "gl_replay.h"
|
||||
#include <dlfcn.h>
|
||||
#include "gl_driver.h"
|
||||
@@ -63,30 +65,35 @@ void GLReplay::CloseReplayContext()
|
||||
{
|
||||
if(glXDestroyCtxProc)
|
||||
{
|
||||
glXMakeContextCurrentProc(m_ReplayCtx.dpy, None, None, NULL);
|
||||
glXMakeContextCurrentProc(m_ReplayCtx.dpy, 0L, 0L, NULL);
|
||||
glXDestroyCtxProc(m_ReplayCtx.dpy, m_ReplayCtx.ctx);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t GLReplay::MakeOutputWindow(void *wn, bool depth)
|
||||
uint64_t GLReplay::MakeOutputWindow(WindowingSystem system, void *data, bool depth)
|
||||
{
|
||||
void **displayAndDrawable = (void **)wn;
|
||||
|
||||
Display *dpy = NULL;
|
||||
GLXDrawable wnd = 0;
|
||||
Drawable draw = 0;
|
||||
|
||||
if(wn)
|
||||
if(system == eWindowingSystem_Xlib)
|
||||
{
|
||||
dpy = (Display *)displayAndDrawable[0];
|
||||
wnd = (GLXDrawable)displayAndDrawable[1];
|
||||
XlibWindowData *xlib = (XlibWindowData *)data;
|
||||
|
||||
dpy = xlib->display;
|
||||
draw = xlib->window;
|
||||
}
|
||||
else
|
||||
else if(system == eWindowingSystem_Unknown)
|
||||
{
|
||||
// allow undefined so that internally we can create a window-less context
|
||||
dpy = XOpenDisplay(NULL);
|
||||
|
||||
if(dpy == NULL)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unexpected window system %u", system);
|
||||
}
|
||||
|
||||
static int visAttribs[] = {GLX_X_RENDERABLE,
|
||||
True,
|
||||
@@ -140,13 +147,19 @@ uint64_t GLReplay::MakeOutputWindow(void *wn, bool depth)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(wnd == 0)
|
||||
GLXDrawable wnd = 0;
|
||||
|
||||
if(draw == 0)
|
||||
{
|
||||
// don't care about pbuffer properties as we won't render directly to this
|
||||
int pbAttribs[] = {GLX_PBUFFER_WIDTH, 32, GLX_PBUFFER_HEIGHT, 32, 0};
|
||||
|
||||
wnd = glXCreatePbufferProc(dpy, fbcfg[0], pbAttribs);
|
||||
}
|
||||
else
|
||||
{
|
||||
wnd = glXCreateWindow(dpy, fbcfg[0], draw, 0);
|
||||
}
|
||||
|
||||
XFree(fbcfg);
|
||||
|
||||
@@ -183,7 +196,7 @@ void GLReplay::DestroyOutputWindow(uint64_t id)
|
||||
WrappedOpenGL &gl = *m_pDriver;
|
||||
gl.glDeleteFramebuffers(1, &outw.BlitData.readFBO);
|
||||
|
||||
glXMakeContextCurrentProc(outw.dpy, None, None, NULL);
|
||||
glXMakeContextCurrentProc(outw.dpy, 0L, 0L, NULL);
|
||||
glXDestroyCtxProc(outw.dpy, outw.ctx);
|
||||
|
||||
m_OutputWindows.erase(it);
|
||||
|
||||
@@ -68,9 +68,11 @@ void GLReplay::CloseReplayContext()
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t GLReplay::MakeOutputWindow(void *wn, bool depth)
|
||||
uint64_t GLReplay::MakeOutputWindow(WindowingSystem system, void *data, bool depth)
|
||||
{
|
||||
HWND w = (HWND)wn;
|
||||
RDCASSERT(system == eWindowingSystem_Win32 || system == eWindowingSystem_Unknown, system);
|
||||
|
||||
HWND w = (HWND)data;
|
||||
|
||||
if(w == NULL)
|
||||
w = CreateWindowEx(WS_EX_CLIENTEDGE, L"renderdocGLclass", L"", WS_OVERLAPPEDWINDOW,
|
||||
|
||||
@@ -25,9 +25,11 @@
|
||||
#include "vk_core.h"
|
||||
#include "vk_replay.h"
|
||||
|
||||
void VulkanReplay::OutputWindow::SetWindowHandle(void *wn)
|
||||
void VulkanReplay::OutputWindow::SetWindowHandle(WindowingSystem system, void *data)
|
||||
{
|
||||
RDCASSERT(system == eWindowingSystem_Android, system);
|
||||
wnd = (ANativeWindow *)wn;
|
||||
m_WindowSystem = system;
|
||||
}
|
||||
|
||||
void VulkanReplay::OutputWindow::CreateSurface(VkInstance inst)
|
||||
|
||||
@@ -246,6 +246,8 @@ private:
|
||||
uint32_t HandlePreCallback(VkCommandBuffer commandBuffer, bool dispatch = false,
|
||||
uint32_t multiDrawOffset = 0);
|
||||
|
||||
vector<WindowingSystem> m_SupportedWindowSystems;
|
||||
|
||||
uint32_t m_FrameCounter;
|
||||
|
||||
PerformanceTimer m_FrameTimer;
|
||||
|
||||
@@ -22,37 +22,60 @@
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#define RENDERDOC_WINDOWING_XLIB 1
|
||||
#define RENDERDOC_WINDOWING_XCB 1
|
||||
|
||||
#include "api/replay/renderdoc_replay.h"
|
||||
|
||||
#include "vk_core.h"
|
||||
#include "vk_replay.h"
|
||||
|
||||
void VulkanReplay::OutputWindow::SetWindowHandle(void *wn)
|
||||
void VulkanReplay::OutputWindow::SetWindowHandle(WindowingSystem system, void *data)
|
||||
{
|
||||
void **connectionScreenWindow = (void **)wn;
|
||||
m_WindowSystem = system;
|
||||
|
||||
connection = (xcb_connection_t *)connectionScreenWindow[0];
|
||||
int scr = (int)(uintptr_t)connectionScreenWindow[1];
|
||||
wnd = (xcb_window_t)(uintptr_t)connectionScreenWindow[2];
|
||||
|
||||
const xcb_setup_t *setup = xcb_get_setup(connection);
|
||||
xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup);
|
||||
while(scr-- > 0)
|
||||
xcb_screen_next(&iter);
|
||||
|
||||
screen = iter.data;
|
||||
if(system == eWindowingSystem_Xlib)
|
||||
{
|
||||
XlibWindowData *xdata = (XlibWindowData *)data;
|
||||
xlib.display = xdata->display;
|
||||
xlib.window = xdata->window;
|
||||
}
|
||||
else if(system == eWindowingSystem_XCB)
|
||||
{
|
||||
XCBWindowData *xdata = (XCBWindowData *)data;
|
||||
xcb.connection = xdata->connection;
|
||||
xcb.window = xdata->window;
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanReplay::OutputWindow::CreateSurface(VkInstance inst)
|
||||
{
|
||||
VkXcbSurfaceCreateInfoKHR createInfo;
|
||||
if(m_WindowSystem == eWindowingSystem_Xlib)
|
||||
{
|
||||
VkXlibSurfaceCreateInfoKHR createInfo;
|
||||
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
|
||||
createInfo.pNext = NULL;
|
||||
createInfo.flags = 0;
|
||||
createInfo.connection = connection;
|
||||
createInfo.window = wnd;
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
|
||||
createInfo.pNext = NULL;
|
||||
createInfo.flags = 0;
|
||||
createInfo.dpy = xlib.display;
|
||||
createInfo.window = xlib.window;
|
||||
|
||||
VkResult vkr = ObjDisp(inst)->CreateXcbSurfaceKHR(Unwrap(inst), &createInfo, NULL, &surface);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
VkResult vkr = ObjDisp(inst)->CreateXlibSurfaceKHR(Unwrap(inst), &createInfo, NULL, &surface);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
}
|
||||
else if(m_WindowSystem == eWindowingSystem_XCB)
|
||||
{
|
||||
VkXcbSurfaceCreateInfoKHR createInfo;
|
||||
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
|
||||
createInfo.pNext = NULL;
|
||||
createInfo.flags = 0;
|
||||
createInfo.connection = xcb.connection;
|
||||
createInfo.window = xcb.window;
|
||||
|
||||
VkResult vkr = ObjDisp(inst)->CreateXcbSurfaceKHR(Unwrap(inst), &createInfo, NULL, &surface);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanReplay::GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h)
|
||||
@@ -62,12 +85,23 @@ void VulkanReplay::GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h
|
||||
|
||||
OutputWindow &outw = m_OutputWindows[id];
|
||||
|
||||
xcb_get_geometry_cookie_t geomCookie =
|
||||
xcb_get_geometry(outw.connection, outw.wnd); // window is a xcb_drawable_t
|
||||
xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply(outw.connection, geomCookie, NULL);
|
||||
if(outw.m_WindowSystem == eWindowingSystem_Xlib)
|
||||
{
|
||||
XWindowAttributes attr = {};
|
||||
XGetWindowAttributes(outw.xlib.display, outw.xlib.window, &attr);
|
||||
|
||||
w = (int32_t)geom->width;
|
||||
h = (int32_t)geom->height;
|
||||
w = (int32_t)attr.width;
|
||||
h = (int32_t)attr.height;
|
||||
}
|
||||
else if(outw.m_WindowSystem == eWindowingSystem_XCB)
|
||||
{
|
||||
xcb_get_geometry_cookie_t geomCookie =
|
||||
xcb_get_geometry(outw.xcb.connection, outw.xcb.window); // window is a xcb_drawable_t
|
||||
xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply(outw.xcb.connection, geomCookie, NULL);
|
||||
|
||||
free(geom);
|
||||
w = (int32_t)geom->width;
|
||||
h = (int32_t)geom->height;
|
||||
|
||||
free(geom);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,24 +57,52 @@ bool WrappedVulkan::AddRequiredExtensions(bool instance, vector<string> &extensi
|
||||
bool oneSurfaceTypeSupported = false;
|
||||
|
||||
#if defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
// don't add duplicates, and only add if supported
|
||||
if(supportedExtensions.find(VK_KHR_XCB_SURFACE_EXTENSION_NAME) != supportedExtensions.end() &&
|
||||
std::find(extensionList.begin(), extensionList.end(), VK_KHR_XCB_SURFACE_EXTENSION_NAME) ==
|
||||
extensionList.end())
|
||||
// check if supported
|
||||
if(supportedExtensions.find(VK_KHR_XCB_SURFACE_EXTENSION_NAME) != supportedExtensions.end())
|
||||
{
|
||||
extensionList.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
|
||||
oneSurfaceTypeSupported = true;
|
||||
|
||||
m_SupportedWindowSystems.push_back(eWindowingSystem_XCB);
|
||||
|
||||
// don't add duplicates
|
||||
if(std::find(extensionList.begin(), extensionList.end(), VK_KHR_XCB_SURFACE_EXTENSION_NAME) ==
|
||||
extensionList.end())
|
||||
{
|
||||
extensionList.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
// don't add duplicates
|
||||
if(supportedExtensions.find(VK_KHR_XLIB_SURFACE_EXTENSION_NAME) != supportedExtensions.end() &&
|
||||
std::find(extensionList.begin(), extensionList.end(), VK_KHR_XLIB_SURFACE_EXTENSION_NAME) ==
|
||||
extensionList.end())
|
||||
// check if supported
|
||||
if(supportedExtensions.find(VK_KHR_XLIB_SURFACE_EXTENSION_NAME) != supportedExtensions.end())
|
||||
{
|
||||
extensionList.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
|
||||
oneSurfaceTypeSupported = true;
|
||||
|
||||
m_SupportedWindowSystems.push_back(eWindowingSystem_Xlib);
|
||||
|
||||
// don't add duplicates
|
||||
if(std::find(extensionList.begin(), extensionList.end(), VK_KHR_XLIB_SURFACE_EXTENSION_NAME) ==
|
||||
extensionList.end())
|
||||
{
|
||||
extensionList.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
|
||||
// must be supported
|
||||
RDCASSERT(supportedExtensions.find(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) !=
|
||||
supportedExtensions.end());
|
||||
|
||||
oneSurfaceTypeSupported = true;
|
||||
m_SupportedWindowSystems.push_back(eWindowingSystem_Android);
|
||||
|
||||
// don't add duplicates, application will have added this but just be sure
|
||||
if(std::find(extensionList.begin(), extensionList.end(),
|
||||
VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == extensionList.end())
|
||||
{
|
||||
extensionList.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -111,10 +139,10 @@ VkBool32 WrappedVulkan::vkGetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalD
|
||||
connection, visual_id);
|
||||
}
|
||||
|
||||
struct xcb_connection_t;
|
||||
namespace Keyboard
|
||||
{
|
||||
void UseConnection(xcb_connection_t *conn);
|
||||
void CloneDisplay(Display *dpy);
|
||||
}
|
||||
|
||||
VkResult WrappedVulkan::vkCreateXcbSurfaceKHR(VkInstance instance,
|
||||
@@ -177,8 +205,7 @@ VkResult WrappedVulkan::vkCreateXlibSurfaceKHR(VkInstance instance,
|
||||
// handle under there somewhere, we just cast. We won't use the resource record for anything
|
||||
wrapped->record = (VkResourceRecord *)pCreateInfo->window;
|
||||
|
||||
// VKTODOLOW Should support Xlib here
|
||||
// Keyboard::UseConnection(pCreateInfo->dpy);
|
||||
Keyboard::CloneDisplay(pCreateInfo->dpy);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -34,13 +34,16 @@
|
||||
#define VULKAN 1
|
||||
#include "data/glsl/debuguniforms.h"
|
||||
|
||||
VulkanReplay::OutputWindow::OutputWindow() : wnd(NULL_WND_HANDLE), width(0), height(0)
|
||||
VulkanReplay::OutputWindow::OutputWindow()
|
||||
: m_WindowSystem(eWindowingSystem_Unknown), width(0), height(0)
|
||||
{
|
||||
surface = VK_NULL_HANDLE;
|
||||
swap = VK_NULL_HANDLE;
|
||||
for(size_t i = 0; i < ARRAY_COUNT(colimg); i++)
|
||||
colimg[i] = VK_NULL_HANDLE;
|
||||
|
||||
WINDOW_HANDLE_INIT;
|
||||
|
||||
fresh = true;
|
||||
|
||||
hasDepth = false;
|
||||
@@ -2733,7 +2736,7 @@ bool VulkanReplay::CheckResizeOutputWindow(uint64_t id)
|
||||
|
||||
OutputWindow &outw = m_OutputWindows[id];
|
||||
|
||||
if(outw.wnd == NULL_WND_HANDLE)
|
||||
if(outw.m_WindowSystem == eWindowingSystem_Unknown)
|
||||
return false;
|
||||
|
||||
int32_t w, h;
|
||||
@@ -3082,15 +3085,20 @@ void VulkanReplay::DestroyOutputWindow(uint64_t id)
|
||||
m_OutputWindows.erase(it);
|
||||
}
|
||||
|
||||
uint64_t VulkanReplay::MakeOutputWindow(void *wn, bool depth)
|
||||
vector<WindowingSystem> VulkanReplay::GetSupportedWindowSystems()
|
||||
{
|
||||
return m_pDriver->m_SupportedWindowSystems;
|
||||
}
|
||||
|
||||
uint64_t VulkanReplay::MakeOutputWindow(WindowingSystem system, void *data, bool depth)
|
||||
{
|
||||
uint64_t id = m_OutputWinID;
|
||||
m_OutputWinID++;
|
||||
|
||||
m_OutputWindows[id].SetWindowHandle(wn);
|
||||
m_OutputWindows[id].SetWindowHandle(system, data);
|
||||
m_OutputWindows[id].m_ResourceManager = GetResourceManager();
|
||||
|
||||
if(wn != NULL)
|
||||
if(system != eWindowingSystem_Unknown)
|
||||
{
|
||||
int32_t w, h;
|
||||
GetOutputWindowDimensions(id, w, h);
|
||||
|
||||
@@ -34,21 +34,29 @@
|
||||
|
||||
#include <windows.h>
|
||||
#define WINDOW_HANDLE_DECL HWND wnd;
|
||||
#define NULL_WND_HANDLE NULL
|
||||
#define WINDOW_HANDLE_INIT wnd = NULL;
|
||||
|
||||
#elif defined(RENDERDOC_PLATFORM_ANDROID)
|
||||
|
||||
#define WINDOW_HANDLE_DECL ANativeWindow *wnd;
|
||||
#define NULL_WND_HANDLE NULL
|
||||
#define WINDOW_HANDLE_INIT wnd = NULL;
|
||||
|
||||
#elif defined(RENDERDOC_PLATFORM_LINUX)
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
#define WINDOW_HANDLE_DECL \
|
||||
xcb_connection_t *connection; \
|
||||
xcb_screen_t *screen; \
|
||||
xcb_window_t wnd;
|
||||
#define NULL_WND_HANDLE xcb_window_t(0)
|
||||
#define WINDOW_HANDLE_DECL \
|
||||
struct \
|
||||
{ \
|
||||
Display *display; \
|
||||
Drawable window; \
|
||||
} xlib; \
|
||||
struct \
|
||||
{ \
|
||||
xcb_connection_t *connection; \
|
||||
xcb_window_t window; \
|
||||
} xcb;
|
||||
#define WINDOW_HANDLE_INIT \
|
||||
RDCEraseEl(xlib); \
|
||||
RDCEraseEl(xcb);
|
||||
|
||||
#else
|
||||
|
||||
@@ -119,7 +127,9 @@ public:
|
||||
|
||||
vector<uint32_t> GetPassEvents(uint32_t eventID);
|
||||
|
||||
uint64_t MakeOutputWindow(void *w, bool depth);
|
||||
vector<WindowingSystem> GetSupportedWindowSystems();
|
||||
|
||||
uint64_t MakeOutputWindow(WindowingSystem system, void *data, bool depth);
|
||||
void DestroyOutputWindow(uint64_t id);
|
||||
bool CheckResizeOutputWindow(uint64_t id);
|
||||
void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h);
|
||||
@@ -223,9 +233,11 @@ private:
|
||||
|
||||
// implemented in vk_replay_platform.cpp
|
||||
void CreateSurface(VkInstance inst);
|
||||
void SetWindowHandle(void *wn);
|
||||
void SetWindowHandle(WindowingSystem system, void *data);
|
||||
|
||||
WINDOW_HANDLE_DECL
|
||||
WindowingSystem m_WindowSystem;
|
||||
|
||||
WINDOW_HANDLE_DECL;
|
||||
|
||||
bool fresh;
|
||||
|
||||
|
||||
@@ -27,9 +27,11 @@
|
||||
|
||||
static int dllLocator = 0;
|
||||
|
||||
void VulkanReplay::OutputWindow::SetWindowHandle(void *wn)
|
||||
void VulkanReplay::OutputWindow::SetWindowHandle(WindowingSystem system, void *data)
|
||||
{
|
||||
wnd = (HWND)wn;
|
||||
RDCASSERT(system == eWindowingSystem_Win32, system);
|
||||
wnd = (HWND)data;
|
||||
m_WindowSystem = system;
|
||||
}
|
||||
|
||||
void VulkanReplay::OutputWindow::CreateSurface(VkInstance inst)
|
||||
|
||||
@@ -52,13 +52,19 @@ bool PlatformHasKeyInput()
|
||||
return true;
|
||||
}
|
||||
|
||||
xcb_connection_t *connection;
|
||||
xcb_key_symbols_t *symbols;
|
||||
Display *CurrentXDisplay = NULL;
|
||||
|
||||
void CloneDisplay(Display *dpy)
|
||||
{
|
||||
if(CurrentXDisplay || dpy == NULL)
|
||||
return;
|
||||
|
||||
CurrentXDisplay = XOpenDisplay(XDisplayString(dpy));
|
||||
}
|
||||
|
||||
xcb_connection_t *connection;
|
||||
xcb_key_symbols_t *symbols;
|
||||
|
||||
void UseConnection(xcb_connection_t *conn)
|
||||
{
|
||||
connection = conn;
|
||||
@@ -74,13 +80,72 @@ void RemoveInputWindow(void *wnd)
|
||||
{
|
||||
}
|
||||
|
||||
bool GetKeyState(int key)
|
||||
bool GetXlibKeyState(int key)
|
||||
{
|
||||
if(CurrentXDisplay == NULL)
|
||||
return false;
|
||||
|
||||
KeySym ks = 0;
|
||||
|
||||
if(key >= eRENDERDOC_Key_A && key <= eRENDERDOC_Key_Z)
|
||||
ks = key;
|
||||
if(key >= eRENDERDOC_Key_0 && key <= eRENDERDOC_Key_9)
|
||||
ks = key;
|
||||
|
||||
switch(key)
|
||||
{
|
||||
case eRENDERDOC_Key_Divide: ks = XK_KP_Divide; break;
|
||||
case eRENDERDOC_Key_Multiply: ks = XK_KP_Multiply; break;
|
||||
case eRENDERDOC_Key_Subtract: ks = XK_KP_Subtract; break;
|
||||
case eRENDERDOC_Key_Plus: ks = XK_KP_Add; break;
|
||||
case eRENDERDOC_Key_F1: ks = XK_F1; break;
|
||||
case eRENDERDOC_Key_F2: ks = XK_F2; break;
|
||||
case eRENDERDOC_Key_F3: ks = XK_F3; break;
|
||||
case eRENDERDOC_Key_F4: ks = XK_F4; break;
|
||||
case eRENDERDOC_Key_F5: ks = XK_F5; break;
|
||||
case eRENDERDOC_Key_F6: ks = XK_F6; break;
|
||||
case eRENDERDOC_Key_F7: ks = XK_F7; break;
|
||||
case eRENDERDOC_Key_F8: ks = XK_F8; break;
|
||||
case eRENDERDOC_Key_F9: ks = XK_F9; break;
|
||||
case eRENDERDOC_Key_F10: ks = XK_F10; break;
|
||||
case eRENDERDOC_Key_F11: ks = XK_F11; break;
|
||||
case eRENDERDOC_Key_F12: ks = XK_F12; break;
|
||||
case eRENDERDOC_Key_Home: ks = XK_Home; break;
|
||||
case eRENDERDOC_Key_End: ks = XK_End; break;
|
||||
case eRENDERDOC_Key_Insert: ks = XK_Insert; break;
|
||||
case eRENDERDOC_Key_Delete: ks = XK_Delete; break;
|
||||
case eRENDERDOC_Key_PageUp: ks = XK_Prior; break;
|
||||
case eRENDERDOC_Key_PageDn: ks = XK_Next; break;
|
||||
case eRENDERDOC_Key_Backspace: ks = XK_BackSpace; break;
|
||||
case eRENDERDOC_Key_Tab: ks = XK_Tab; break;
|
||||
case eRENDERDOC_Key_PrtScrn: ks = XK_Print; break;
|
||||
case eRENDERDOC_Key_Pause: ks = XK_Pause; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if(ks == 0)
|
||||
return false;
|
||||
|
||||
KeyCode kc = XKeysymToKeycode(CurrentXDisplay, ks);
|
||||
|
||||
char keyState[32];
|
||||
XQueryKeymap(CurrentXDisplay, keyState);
|
||||
|
||||
int byteIdx = (kc / 8);
|
||||
int bitMask = 1 << (kc % 8);
|
||||
|
||||
uint8_t keyByte = (uint8_t)keyState[byteIdx];
|
||||
|
||||
return (keyByte & bitMask) != 0;
|
||||
}
|
||||
|
||||
bool GetXCBKeyState(int key)
|
||||
{
|
||||
if(symbols == NULL)
|
||||
return false;
|
||||
|
||||
KeySym ks = 0;
|
||||
|
||||
if(key >= eRENDERDOC_Key_A && key <= eRENDERDOC_Key_Z)
|
||||
ks = key;
|
||||
if(key >= eRENDERDOC_Key_0 && key <= eRENDERDOC_Key_9)
|
||||
@@ -143,6 +208,11 @@ bool GetKeyState(int key)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool GetKeyState(int key)
|
||||
{
|
||||
return GetXCBKeyState(key) || GetXlibKeyState(key);
|
||||
}
|
||||
}
|
||||
|
||||
namespace FileIO
|
||||
|
||||
@@ -134,7 +134,9 @@ class IReplayDriver : public IRemoteDriver
|
||||
public:
|
||||
virtual bool IsRemoteProxy() = 0;
|
||||
|
||||
virtual uint64_t MakeOutputWindow(void *w, bool depth) = 0;
|
||||
virtual vector<WindowingSystem> GetSupportedWindowSystems() = 0;
|
||||
|
||||
virtual uint64_t MakeOutputWindow(WindowingSystem system, void *data, bool depth) = 0;
|
||||
virtual void DestroyOutputWindow(uint64_t id) = 0;
|
||||
virtual bool CheckResizeOutputWindow(uint64_t id) = 0;
|
||||
virtual void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h) = 0;
|
||||
|
||||
@@ -23,12 +23,46 @@
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(RENDERDOC_PLATFORM_LINUX)
|
||||
#define RENDERDOC_WINDOWING_XLIB 1
|
||||
#define RENDERDOC_WINDOWING_XCB 1
|
||||
#endif
|
||||
|
||||
#include "common/common.h"
|
||||
#include "maths/matrix.h"
|
||||
#include "serialise/string_utils.h"
|
||||
#include "replay_renderer.h"
|
||||
|
||||
ReplayOutput::ReplayOutput(ReplayRenderer *parent, void *w, OutputType type)
|
||||
static uint64_t GetHandle(WindowingSystem system, void *data)
|
||||
{
|
||||
#if defined(RENDERDOC_PLATFORM_LINUX)
|
||||
|
||||
if(system == eWindowingSystem_Xlib)
|
||||
return (uint64_t)((XlibWindowData *)data)->window;
|
||||
|
||||
if(system == eWindowingSystem_XCB)
|
||||
return (uint64_t)((XCBWindowData *)data)->window;
|
||||
|
||||
RDCERR("Unrecognised window system %d", system);
|
||||
|
||||
return 0;
|
||||
|
||||
#elif defined(RENDERDOC_PLATFORM_WIN32)
|
||||
|
||||
RDCASSERT(system == eWindowingSystem_Win32);
|
||||
return (uint64_t)data; // HWND
|
||||
|
||||
#elif defined(RENDERDOC_PLATFORM_ANDROID)
|
||||
|
||||
RDCASSERT(system == eWindowingSystem_Android);
|
||||
return (uint64_t)data; // ANativeWindow *
|
||||
|
||||
#else
|
||||
RDCFATAL("No windowing data defined for this platform! Must be implemented for replay outputs");
|
||||
#endif
|
||||
}
|
||||
|
||||
ReplayOutput::ReplayOutput(ReplayRenderer *parent, WindowingSystem system, void *data, OutputType type)
|
||||
{
|
||||
m_pRenderer = parent;
|
||||
|
||||
@@ -45,7 +79,6 @@ ReplayOutput::ReplayOutput(ReplayRenderer *parent, void *w, OutputType type)
|
||||
|
||||
RDCEraseEl(m_RenderData);
|
||||
|
||||
m_PixelContext.wndHandle = 0;
|
||||
m_PixelContext.outputID = 0;
|
||||
m_PixelContext.texture = ResourceId();
|
||||
m_PixelContext.depthMode = false;
|
||||
@@ -55,8 +88,9 @@ ReplayOutput::ReplayOutput(ReplayRenderer *parent, void *w, OutputType type)
|
||||
|
||||
m_Config.m_Type = type;
|
||||
|
||||
if(w)
|
||||
m_MainOutput.outputID = m_pDevice->MakeOutputWindow(w, type == eOutputType_MeshDisplay);
|
||||
if(system != eWindowingSystem_Unknown)
|
||||
m_MainOutput.outputID =
|
||||
m_pDevice->MakeOutputWindow(system, data, type == eOutputType_MeshDisplay);
|
||||
else
|
||||
m_MainOutput.outputID = 0;
|
||||
m_MainOutput.texture = ResourceId();
|
||||
@@ -179,10 +213,9 @@ bool ReplayOutput::ClearThumbnails()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReplayOutput::SetPixelContext(void *wnd)
|
||||
bool ReplayOutput::SetPixelContext(WindowingSystem system, void *data)
|
||||
{
|
||||
m_PixelContext.wndHandle = wnd;
|
||||
m_PixelContext.outputID = m_pDevice->MakeOutputWindow(m_PixelContext.wndHandle, false);
|
||||
m_PixelContext.outputID = m_pDevice->MakeOutputWindow(system, data, false);
|
||||
m_PixelContext.texture = ResourceId();
|
||||
m_PixelContext.depthMode = false;
|
||||
|
||||
@@ -191,11 +224,12 @@ bool ReplayOutput::SetPixelContext(void *wnd)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReplayOutput::AddThumbnail(void *wnd, ResourceId texID, FormatComponentType typeHint)
|
||||
bool ReplayOutput::AddThumbnail(WindowingSystem system, void *data, ResourceId texID,
|
||||
FormatComponentType typeHint)
|
||||
{
|
||||
OutputPair p;
|
||||
|
||||
RDCASSERT(wnd);
|
||||
RDCASSERT(data);
|
||||
|
||||
bool depthMode = false;
|
||||
|
||||
@@ -211,7 +245,7 @@ bool ReplayOutput::AddThumbnail(void *wnd, ResourceId texID, FormatComponentType
|
||||
|
||||
for(size_t i = 0; i < m_Thumbnails.size(); i++)
|
||||
{
|
||||
if(m_Thumbnails[i].wndHandle == wnd)
|
||||
if(m_Thumbnails[i].wndHandle == GetHandle(system, data))
|
||||
{
|
||||
m_Thumbnails[i].texture = texID;
|
||||
|
||||
@@ -225,8 +259,8 @@ bool ReplayOutput::AddThumbnail(void *wnd, ResourceId texID, FormatComponentType
|
||||
}
|
||||
}
|
||||
|
||||
p.wndHandle = wnd;
|
||||
p.outputID = m_pDevice->MakeOutputWindow(p.wndHandle, false);
|
||||
p.wndHandle = GetHandle(system, data);
|
||||
p.outputID = m_pDevice->MakeOutputWindow(system, data, false);
|
||||
p.texture = texID;
|
||||
p.depthMode = depthMode;
|
||||
p.typeHint = typeHint;
|
||||
@@ -700,10 +734,11 @@ extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_ClearThumbnails(Replay
|
||||
return output->ClearThumbnails();
|
||||
}
|
||||
extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_AddThumbnail(ReplayOutput *output,
|
||||
void *wnd, ResourceId texID,
|
||||
WindowingSystem system,
|
||||
void *data, ResourceId texID,
|
||||
FormatComponentType typeHint)
|
||||
{
|
||||
return output->AddThumbnail(wnd, texID, typeHint);
|
||||
return output->AddThumbnail(system, data, texID, typeHint);
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_Display(ReplayOutput *output)
|
||||
@@ -712,9 +747,10 @@ extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_Display(ReplayOutput *
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetPixelContext(ReplayOutput *output,
|
||||
void *wnd)
|
||||
WindowingSystem system,
|
||||
void *data)
|
||||
{
|
||||
return output->SetPixelContext(wnd);
|
||||
return output->SetPixelContext(system, data);
|
||||
}
|
||||
extern "C" RENDERDOC_API bool32 RENDERDOC_CC
|
||||
ReplayOutput_SetPixelContextLocation(ReplayOutput *output, uint32_t x, uint32_t y)
|
||||
|
||||
@@ -1415,9 +1415,15 @@ bool ReplayRenderer::GetCBufferVariableContents(ResourceId shader, const char *e
|
||||
return true;
|
||||
}
|
||||
|
||||
ReplayOutput *ReplayRenderer::CreateOutput(void *wndhandle, OutputType type)
|
||||
void ReplayRenderer::GetSupportedWindowSystems(rdctype::array<WindowingSystem> *systems)
|
||||
{
|
||||
ReplayOutput *out = new ReplayOutput(this, wndhandle, type);
|
||||
if(systems)
|
||||
*systems = m_pDevice->GetSupportedWindowSystems();
|
||||
}
|
||||
|
||||
ReplayOutput *ReplayRenderer::CreateOutput(WindowingSystem system, void *data, OutputType type)
|
||||
{
|
||||
ReplayOutput *out = new ReplayOutput(this, system, data, type);
|
||||
|
||||
m_Outputs.push_back(out);
|
||||
|
||||
@@ -1668,11 +1674,16 @@ extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_GetAPIProperties(Repla
|
||||
*props = rend->GetAPIProperties();
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API ReplayOutput *RENDERDOC_CC ReplayRenderer_CreateOutput(ReplayRenderer *rend,
|
||||
void *handle,
|
||||
OutputType type)
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_GetSupportedWindowSystems(
|
||||
ReplayRenderer *rend, rdctype::array<WindowingSystem> *systems)
|
||||
{
|
||||
return rend->CreateOutput(handle, type);
|
||||
rend->GetSupportedWindowSystems(systems);
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API ReplayOutput *RENDERDOC_CC ReplayRenderer_CreateOutput(
|
||||
ReplayRenderer *rend, WindowingSystem system, void *data, OutputType type)
|
||||
{
|
||||
return rend->CreateOutput(system, data, type);
|
||||
}
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_Shutdown(ReplayRenderer *rend)
|
||||
{
|
||||
|
||||
@@ -43,12 +43,13 @@ public:
|
||||
bool SetMeshDisplay(const MeshDisplay &o);
|
||||
|
||||
bool ClearThumbnails();
|
||||
bool AddThumbnail(void *wnd, ResourceId texID, FormatComponentType typeHint);
|
||||
bool AddThumbnail(WindowingSystem system, void *data, ResourceId texID,
|
||||
FormatComponentType typeHint);
|
||||
|
||||
bool Display();
|
||||
|
||||
OutputType GetType() { return m_Config.m_Type; }
|
||||
bool SetPixelContext(void *wnd);
|
||||
bool SetPixelContext(WindowingSystem system, void *data);
|
||||
bool SetPixelContextLocation(uint32_t x, uint32_t y);
|
||||
void DisablePixelContext();
|
||||
|
||||
@@ -58,7 +59,7 @@ public:
|
||||
uint32_t PickVertex(uint32_t eventID, uint32_t x, uint32_t y);
|
||||
|
||||
private:
|
||||
ReplayOutput(ReplayRenderer *parent, void *w, OutputType type);
|
||||
ReplayOutput(ReplayRenderer *parent, WindowingSystem system, void *data, OutputType type);
|
||||
virtual ~ReplayOutput();
|
||||
|
||||
void SetFrameEvent(int eventID);
|
||||
@@ -82,7 +83,7 @@ private:
|
||||
{
|
||||
ResourceId texture;
|
||||
bool depthMode;
|
||||
void *wndHandle;
|
||||
uint64_t wndHandle;
|
||||
FormatComponentType typeHint;
|
||||
uint64_t outputID;
|
||||
|
||||
@@ -191,7 +192,9 @@ public:
|
||||
ResourceId buffer, uint64_t offs,
|
||||
rdctype::array<ShaderVariable> *vars);
|
||||
|
||||
ReplayOutput *CreateOutput(void *handle, OutputType type);
|
||||
void GetSupportedWindowSystems(rdctype::array<WindowingSystem> *systems);
|
||||
|
||||
ReplayOutput *CreateOutput(WindowingSystem, void *data, OutputType type);
|
||||
|
||||
void ShutdownOutput(ReplayOutput *output);
|
||||
void Shutdown();
|
||||
|
||||
@@ -15,7 +15,7 @@ elseif(UNIX)
|
||||
list(APPEND includes PRIVATE ${OPENGL_INCLUDE_DIR})
|
||||
list(APPEND libraries PRIVATE ${OPENGL_gl_LIBRARY})
|
||||
|
||||
list(APPEND libraries PRIVATE -lxcb)
|
||||
list(APPEND libraries PRIVATE -lxcb -lX11 -lX11-xcb)
|
||||
endif()
|
||||
|
||||
if(ANDROID)
|
||||
|
||||
@@ -47,8 +47,8 @@ void DisplayRendererPreview(ReplayRenderer *renderer, TextureDisplay &displayCfg
|
||||
{
|
||||
ANativeWindow *connectionScreenWindow = android_state->window;
|
||||
|
||||
ReplayOutput *out =
|
||||
ReplayRenderer_CreateOutput(renderer, connectionScreenWindow, eOutputType_TexDisplay);
|
||||
ReplayOutput *out = ReplayRenderer_CreateOutput(renderer, eWindowingSystem_Android,
|
||||
connectionScreenWindow, eOutputType_TexDisplay);
|
||||
|
||||
OutputConfig c = {eOutputType_TexDisplay};
|
||||
|
||||
|
||||
@@ -24,23 +24,47 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "renderdoccmd.h"
|
||||
#include <X11/Xlib-xcb.h>
|
||||
#include <iconv.h>
|
||||
#include <locale.h>
|
||||
#include <replay/renderdoc_replay.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <xcb/xcb.h>
|
||||
#include <string>
|
||||
|
||||
#define RENDERDOC_WINDOWING_XLIB 1
|
||||
#define RENDERDOC_WINDOWING_XCB 1
|
||||
#include <replay/renderdoc_replay.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
void DisplayRendererPreview(ReplayRenderer *renderer, TextureDisplay &displayCfg, uint32_t width,
|
||||
uint32_t height)
|
||||
{
|
||||
int scr;
|
||||
// need to create a hybrid setup xlib and xcb in case only one or the other is supported.
|
||||
// We'll prefer xcb
|
||||
|
||||
Display *display = XOpenDisplay(NULL);
|
||||
|
||||
if(display == NULL)
|
||||
{
|
||||
std::cerr << "Couldn't open X Display" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
int scr = DefaultScreen(display);
|
||||
|
||||
xcb_connection_t *connection = XGetXCBConnection(display);
|
||||
|
||||
if(connection == NULL)
|
||||
{
|
||||
XCloseDisplay(display);
|
||||
std::cerr << "Couldn't get XCB connection from Xlib Display" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
XSetEventQueueOwner(display, XCBOwnsEventQueue);
|
||||
|
||||
xcb_connection_t *connection = xcb_connect(NULL, &scr);
|
||||
const xcb_setup_t *setup = xcb_get_setup(connection);
|
||||
xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup);
|
||||
while(scr-- > 0)
|
||||
@@ -76,11 +100,49 @@ void DisplayRendererPreview(ReplayRenderer *renderer, TextureDisplay &displayCfg
|
||||
|
||||
xcb_map_window(connection, window);
|
||||
|
||||
void *connectionScreenWindow[] = {(void *)connection, (void *)(uintptr_t)scr,
|
||||
(void *)(uintptr_t)window};
|
||||
rdctype::array<WindowingSystem> systems;
|
||||
ReplayRenderer_GetSupportedWindowSystems(renderer, &systems);
|
||||
|
||||
ReplayOutput *out =
|
||||
ReplayRenderer_CreateOutput(renderer, connectionScreenWindow, eOutputType_TexDisplay);
|
||||
bool xcb = false, xlib = false;
|
||||
|
||||
for(int32_t i = 0; i < systems.count; i++)
|
||||
{
|
||||
if(systems[i] == eWindowingSystem_Xlib)
|
||||
xlib = true;
|
||||
if(systems[i] == eWindowingSystem_XCB)
|
||||
xcb = true;
|
||||
}
|
||||
|
||||
ReplayOutput *out = NULL;
|
||||
|
||||
// prefer xcb
|
||||
if(xcb)
|
||||
{
|
||||
XCBWindowData windowData;
|
||||
windowData.connection = connection;
|
||||
windowData.window = window;
|
||||
|
||||
out = ReplayRenderer_CreateOutput(renderer, eWindowingSystem_XCB, &windowData,
|
||||
eOutputType_TexDisplay);
|
||||
}
|
||||
else if(xlib)
|
||||
{
|
||||
XlibWindowData windowData;
|
||||
windowData.display = display;
|
||||
windowData.window = (Drawable)window; // safe to cast types
|
||||
|
||||
out = ReplayRenderer_CreateOutput(renderer, eWindowingSystem_Xlib, &windowData,
|
||||
eOutputType_TexDisplay);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Neither XCB nor XLib are supported, can't create window." << std::endl;
|
||||
std::cerr << "Supported systems: ";
|
||||
for(int32_t i = 0; i < systems.count; i++)
|
||||
std::cerr << systems[i] << std::endl;
|
||||
std::cerr << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
OutputConfig c = {eOutputType_TexDisplay};
|
||||
|
||||
|
||||
@@ -232,7 +232,8 @@ void DisplayRendererPreview(ReplayRenderer *renderer, TextureDisplay &displayCfg
|
||||
ShowWindow(wnd, SW_SHOW);
|
||||
UpdateWindow(wnd);
|
||||
|
||||
ReplayOutput *out = ReplayRenderer_CreateOutput(renderer, wnd, eOutputType_TexDisplay);
|
||||
ReplayOutput *out =
|
||||
ReplayRenderer_CreateOutput(renderer, eWindowingSystem_Win32, wnd, eOutputType_TexDisplay);
|
||||
|
||||
OutputConfig c = {eOutputType_TexDisplay};
|
||||
|
||||
|
||||
@@ -88,13 +88,13 @@ namespace renderdoc
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool ReplayOutput_ClearThumbnails(IntPtr real);
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool ReplayOutput_AddThumbnail(IntPtr real, IntPtr wnd, ResourceId texID, FormatComponentType typeHint);
|
||||
private static extern bool ReplayOutput_AddThumbnail(IntPtr real, UInt32 windowSystem, IntPtr wnd, ResourceId texID, FormatComponentType typeHint);
|
||||
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool ReplayOutput_Display(IntPtr real);
|
||||
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool ReplayOutput_SetPixelContext(IntPtr real, IntPtr wnd);
|
||||
private static extern bool ReplayOutput_SetPixelContext(IntPtr real, UInt32 windowSystem, IntPtr wnd);
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool ReplayOutput_SetPixelContextLocation(IntPtr real, UInt32 x, UInt32 y);
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
@@ -132,7 +132,8 @@ namespace renderdoc
|
||||
}
|
||||
public bool AddThumbnail(IntPtr wnd, ResourceId texID, FormatComponentType typeHint)
|
||||
{
|
||||
return ReplayOutput_AddThumbnail(m_Real, wnd, texID, typeHint);
|
||||
// 1 == eWindowingSystem_Win32
|
||||
return ReplayOutput_AddThumbnail(m_Real, 1u, wnd, texID, typeHint);
|
||||
}
|
||||
|
||||
public bool Display()
|
||||
@@ -142,7 +143,8 @@ namespace renderdoc
|
||||
|
||||
public bool SetPixelContext(IntPtr wnd)
|
||||
{
|
||||
return ReplayOutput_SetPixelContext(m_Real, wnd);
|
||||
// 1 == eWindowingSystem_Win32
|
||||
return ReplayOutput_SetPixelContext(m_Real, 1u, wnd);
|
||||
}
|
||||
public bool SetPixelContextLocation(UInt32 x, UInt32 y)
|
||||
{
|
||||
@@ -194,7 +196,7 @@ namespace renderdoc
|
||||
private static extern void ReplayRenderer_GetAPIProperties(IntPtr real, IntPtr propsOut);
|
||||
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern IntPtr ReplayRenderer_CreateOutput(IntPtr real, IntPtr WindowHandle, OutputType type);
|
||||
private static extern IntPtr ReplayRenderer_CreateOutput(IntPtr real, UInt32 windowSystem, IntPtr WindowHandle, OutputType type);
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void ReplayRenderer_ShutdownOutput(IntPtr real, IntPtr replayOutput);
|
||||
|
||||
@@ -309,7 +311,9 @@ namespace renderdoc
|
||||
|
||||
public ReplayOutput CreateOutput(IntPtr WindowHandle, OutputType type)
|
||||
{
|
||||
IntPtr ret = ReplayRenderer_CreateOutput(m_Real, WindowHandle, type);
|
||||
// 0 == eWindowingSystem_Unknown
|
||||
// 1 == eWindowingSystem_Win32
|
||||
IntPtr ret = ReplayRenderer_CreateOutput(m_Real, WindowHandle == IntPtr.Zero ? 0u : 1u, WindowHandle, type);
|
||||
|
||||
if (ret == IntPtr.Zero)
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user