Temporarily make renderdoccmd use xcb, as xlib isn't supported by ICD

This commit is contained in:
baldurk
2015-08-30 19:36:16 +02:00
parent 406e06d943
commit 6a6273e591
2 changed files with 77 additions and 45 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ MACROS=-DLINUX \
-DGIT_COMMIT_HASH="\"$(COMMIT)\""
CFLAGS=-c -Wall -Werror -fPIC $(MACROS) -I../renderdoc/api/
CPPFLAGS=-std=c++11 -g -Wno-unused -Wno-unknown-pragmas -Wno-reorder
LDFLAGS=-L../renderdoc/ -lrenderdoc -lGL -lX11 -Wl,-rpath,'$$ORIGIN/'
LDFLAGS=-L../renderdoc/ -lrenderdoc -lGL -lxcb -Wl,-rpath,'$$ORIGIN/'
OBJDIR=.obj
OBJECTS=renderdoccmd.o renderdoccmd_linux.o
+76 -44
View File
@@ -28,10 +28,7 @@
#include <locale.h>
#include <iconv.h>
#include <X11/X.h>
#include <X11/keysym.h>
#include <X11/Xlib.h>
#include <GL/glx.h>
#include <xcb/xcb.h>
#include <unistd.h>
@@ -49,49 +46,58 @@ string GetUsername()
void DisplayRendererPreview(ReplayRenderer *renderer, TextureDisplay displayCfg)
{
Display *dpy = XOpenDisplay(NULL);
int scr;
if(dpy == NULL) return;
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) xcb_screen_next(&iter);
static int visAttribs[] = {
GLX_X_RENDERABLE, True,
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_ALPHA_SIZE, 8,
GLX_DOUBLEBUFFER, True,
0
};
int numCfgs = 0;
GLXFBConfig *fbcfg = glXChooseFBConfig(dpy, DefaultScreen(dpy), visAttribs, &numCfgs);
xcb_screen_t *screen = iter.data;
if(fbcfg == NULL)
{
XCloseDisplay(dpy);
return;
}
uint32_t value_mask, value_list[32];
XVisualInfo *vInfo = glXGetVisualFromFBConfig(dpy, fbcfg[0]);
xcb_window_t window = xcb_generate_id(connection);
XSetWindowAttributes swa = {0};
swa.event_mask = StructureNotifyMask;
swa.colormap = XCreateColormap(dpy, RootWindow(dpy, vInfo->screen), vInfo->visual, AllocNone);
value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
value_list[0] = screen->black_pixel;
value_list[1] = XCB_EVENT_MASK_KEY_RELEASE |
XCB_EVENT_MASK_EXPOSURE |
XCB_EVENT_MASK_STRUCTURE_NOTIFY;
Window win = XCreateWindow(dpy, RootWindow(dpy, vInfo->screen), 200, 200, 1280, 720,
0, vInfo->depth, InputOutput, vInfo->visual,
CWBorderPixel | CWColormap | CWEventMask, &swa);
xcb_create_window(connection,
XCB_COPY_FROM_PARENT,
window, screen->root,
0, 0, 1280, 720, 0,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
screen->root_visual,
value_mask, value_list);
XStoreName(dpy, win, "renderdoccmd");
XMapWindow(dpy, win);
/* Magic code that will send notification when window is destroyed */
xcb_intern_atom_cookie_t cookie = xcb_intern_atom(connection, 1, 12,
"WM_PROTOCOLS");
xcb_intern_atom_reply_t* reply = xcb_intern_atom_reply(connection, cookie, 0);
//GLXWindow glwnd = glXCreateWindow(dpy, fbcfg[0], win, NULL);
xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(connection, 0, 16, "WM_DELETE_WINDOW");
xcb_intern_atom_reply_t *atom_wm_delete_window = xcb_intern_atom_reply(connection, cookie2, 0);
//void *displayAndDrawable[] = { (void *)dpy, (void *)glwnd };
xcb_change_property (connection,
XCB_PROP_MODE_REPLACE,
window,
XCB_ATOM_WM_NAME,
XCB_ATOM_STRING,
8,
sizeof ("renderdoccmd")-1,
"renderdoccmd" );
void *displayAndDrawable[] = { (void *)dpy, (void *)win };
xcb_change_property(connection, XCB_PROP_MODE_REPLACE,
window, (*reply).atom, 4, 32, 1,
&(*atom_wm_delete_window).atom);
free(reply);
xcb_map_window(connection, window);
void *displayAndDrawable[] = { (void *)connection, (void *)screen, (void *)(size_t)window };
ReplayOutput *out = ReplayRenderer_CreateOutput(renderer, displayAndDrawable);
@@ -100,24 +106,50 @@ void DisplayRendererPreview(ReplayRenderer *renderer, TextureDisplay displayCfg)
ReplayOutput_SetOutputConfig(out, c);
ReplayOutput_SetTextureDisplay(out, displayCfg);
xcb_flush(connection);
bool done = false;
while(!done)
{
while(XPending(dpy) > 0)
xcb_generic_event_t *event;
event = xcb_poll_for_event(connection);
if (event)
{
XEvent event = {0};
XNextEvent(dpy, &event);
switch(event.type)
switch (event->response_type & 0x7f)
{
case ButtonPress: done = true;
default: break;
case XCB_EXPOSE:
ReplayRenderer_SetFrameEvent(renderer, 0, 10000000+rand()%1000);
ReplayOutput_Display(out);
break;
case XCB_CLIENT_MESSAGE:
if((*(xcb_client_message_event_t*)event).data.data32[0] ==
(*atom_wm_delete_window).atom) {
done = true;
}
break;
case XCB_KEY_RELEASE:
{
const xcb_key_release_event_t *key =
(const xcb_key_release_event_t *) event;
if (key->detail == 0x9)
done = true;
}
break;
case XCB_DESTROY_NOTIFY:
done = true;
break;
default:
break;
}
free(event);
}
ReplayRenderer_SetFrameEvent(renderer, 0, 10000000+rand()%1000);
ReplayOutput_Display(out);
usleep(40000);
usleep(100000);
}
}