Skip to content

Commit d241793

Browse files
committed
vkreplay: Add support for fullscreen replay
Change-Id: Ie5a867938a87c5e7de607c34552aa0cf696373af
1 parent 9ecd86f commit d241793

File tree

11 files changed

+117
-25
lines changed

11 files changed

+117
-25
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ before_install:
4141
- |
4242
if [[ "$VULKAN_BUILD_TARGET" == "LINUX" ]]; then
4343
sudo apt-get -qq update
44-
sudo apt-get -y install libxkbcommon-dev libwayland-dev libmirclient-dev libxrandr-dev libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev
44+
sudo apt-get -y install libxkbcommon-dev libwayland-dev libmirclient-dev libxrandr-dev libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-ewmh-dev
4545
# Needed for devsim test
4646
sudo apt-get -y install jq
4747
fi

BUILD.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ These additional packages are needed for building the components in this repo.
2020
# Dependencies from included submodule components
2121
sudo apt-get install git cmake build-essential bison libx11-xcb-dev libxkbcommon-dev libmirclient-dev libwayland-dev libxrandr-dev
2222
# Additional dependencies for this repo:
23-
sudo apt-get install wget autotools-dev libxcb-keysyms1 libxcb-keysyms1-dev
23+
sudo apt-get install wget autotools-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-ewmh-dev
2424
# If performing 32-bit builds, you will also need:
2525
sudo apt-get install libc6-dev-i386 g++-multilib
2626
```

vktrace/vktrace_replay/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
2020
add_library(${XCB_DISPLAY_LIB} SHARED ${XCB_SRC_LIST} ${XCB_HDR_LIST})
2121

2222
target_link_libraries(${XCB_DISPLAY_LIB}
23-
xcb
23+
xcb-randr xcb-ewmh xcb
2424
vktrace_common
2525
)
2626

vktrace/vktrace_replay/vkreplay_main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,7 @@ int vkreplay_main(int argc, char** argv, vktrace_replay::ReplayDisplayImp* pDisp
555555

556556
// Create window. Initial size is 100x100. It will later get resized to the size
557557
// used by the traced app. The resize will happen during playback of swapchain functions.
558-
vktrace_replay::ReplayDisplay disp(100, 100, false);
558+
vktrace_replay::ReplayDisplay disp(100, 100);
559559

560560
// Create display
561561
#if defined(PLATFORM_LINUX) && !defined(ANDROID)

vktrace/vktrace_replay/vkreplay_vkdisplay.cpp

100644100755
Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,16 @@ int vkDisplayWin32::create_window(const unsigned int width, const unsigned int h
197197
vktrace_LogError("Failed to create window");
198198
return -1;
199199
}
200+
201+
// Get and save screen size
202+
RECT sr;
203+
if (!GetWindowRect(GetDesktopWindow(), &sr)) {
204+
vktrace_LogError("Failed to get size of screen");
205+
return -1;
206+
}
207+
m_screenWidth = sr.right;
208+
m_screenHeight = sr.bottom;
209+
200210
// TODO : Not sure of best place to put this, but I have all the info I need here so just setting it all here for now
201211
m_surface.base.platform = VK_ICD_WSI_PLATFORM_WIN32;
202212
m_surface.hinstance = wcex.hInstance;
@@ -209,10 +219,19 @@ void vkDisplayWin32::resize_window(const unsigned int width, const unsigned int
209219
if (width != m_windowWidth || height != m_windowHeight) {
210220
m_windowWidth = width;
211221
m_windowHeight = height;
212-
213-
RECT wr = {0, 0, (LONG)width, (LONG)height};
214-
AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
215-
SetWindowPos(get_window_handle(), HWND_TOP, 0, 0, wr.right - wr.left, wr.bottom - wr.top, SWP_NOMOVE);
222+
if (width >= m_screenWidth || height >= m_screenHeight) {
223+
// Make window full screen w/o borders
224+
BOOL rval;
225+
rval = (NULL != SetWindowLongPtr(m_windowHandle, GWL_STYLE, WS_VISIBLE | WS_POPUP));
226+
rval &= SetWindowPos(m_windowHandle, HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED);
227+
if (!rval) {
228+
vktrace_LogError("Failed to set window size to %d %d", width, height);
229+
}
230+
} else {
231+
RECT wr = {0, 0, (LONG)width, (LONG)height};
232+
AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
233+
SetWindowPos(m_windowHandle, HWND_TOP, 0, 0, wr.right - wr.left, wr.bottom - wr.top, SWP_NOMOVE);
234+
}
216235

217236
// Make sure window is visible.
218237
ShowWindow(m_windowHandle, SW_SHOWDEFAULT);

vktrace/vktrace_replay/vkreplay_vkdisplay.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,11 @@ class vkDisplayXcb : public vktrace_replay::ReplayDisplayImp {
6464
xcb_screen_t *m_pXcbScreen;
6565
xcb_window_t m_XcbWindow;
6666
xcb_intern_atom_reply_t *atom_wm_delete_window;
67-
// VkPlatformHandleXcbKHR m_XcbPlatformHandle;
6867

6968
unsigned int m_windowWidth;
7069
unsigned int m_windowHeight;
70+
unsigned int m_screenWidth;
71+
unsigned int m_screenHeight;
7172
std::vector<VkExtent2D> imageExtents;
7273
std::vector<VkImage> imageHandles;
7374
std::vector<VkDeviceMemory> imageMemory;
@@ -115,6 +116,7 @@ class vkDisplayWayland : public vktrace_replay::ReplayDisplayImp {
115116
struct wl_seat *m_seat;
116117
struct wl_pointer *m_pointer;
117118
struct wl_keyboard *m_keyboard;
119+
struct wl_output *m_output;
118120

119121
static void handle_ping(void *data, wl_shell_surface *shell_surface, uint32_t serial);
120122
static void handle_configure(void *data, wl_shell_surface *shell_surface, uint32_t edges, int32_t width, int32_t height);
@@ -142,9 +144,16 @@ class vkDisplayWayland : public vktrace_replay::ReplayDisplayImp {
142144
static void registry_handle_global(void *data, wl_registry *registry, uint32_t id, const char *interface, uint32_t version);
143145
static void registry_handle_global_remove(void *data, wl_registry *registry, uint32_t name);
144146
static struct wl_registry_listener registry_listener;
147+
static void output_handle_geometry(void *data, struct wl_output *wl_output, int x, int y, int physical_width,
148+
int physical_height, int subpixel, const char *make, const char *model, int transform);
149+
static void output_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags, int width, int height, int refresh);
150+
static struct wl_output_listener output_listener;
145151

146152
unsigned int m_windowWidth;
147153
unsigned int m_windowHeight;
154+
unsigned int m_screenWidth;
155+
unsigned int m_screenHeight;
156+
unsigned int m_refresh;
148157
std::vector<VkExtent2D> imageExtents;
149158
std::vector<VkImage> imageHandles;
150159
std::vector<VkDeviceMemory> imageMemory;
@@ -230,6 +239,9 @@ class vkDisplayWin32 : public vktrace_replay::ReplayDisplayImp {
230239

231240
unsigned int m_windowWidth;
232241
unsigned int m_windowHeight;
242+
unsigned int m_screenWidth;
243+
unsigned int m_screenHeight;
244+
233245
std::vector<VkExtent2D> imageExtents;
234246
std::vector<VkImage> imageHandles;
235247
std::vector<VkDeviceMemory> imageMemory;
@@ -245,4 +257,4 @@ class vkDisplayWin32 : public vktrace_replay::ReplayDisplayImp {
245257
bool m_pause = false;
246258
bool m_quit = false;
247259
};
248-
#endif
260+
#endif

vktrace/vktrace_replay/vkreplay_vkdisplay_wayland.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ vkDisplayWayland::vkDisplayWayland() : m_windowWidth(0), m_windowHeight(0) {
4949

5050
registry_listener.global = registry_handle_global;
5151
registry_listener.global_remove = registry_handle_global_remove;
52+
53+
output_listener.geometry = output_handle_geometry;
54+
output_listener.mode = output_handle_mode;
5255
}
5356

5457
vkDisplayWayland::~vkDisplayWayland() {
@@ -116,6 +119,11 @@ void vkDisplayWayland::resize_window(const unsigned int width, const unsigned in
116119
if (width != m_windowWidth || height != m_windowHeight) {
117120
m_windowWidth = width;
118121
m_windowHeight = height;
122+
if (width >= m_screenWidth || height >= m_screenHeight) {
123+
// Make window full screen
124+
wl_shell_surface_set_fullscreen(m_shell_surface, WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, m_refresh, m_output);
125+
}
126+
119127
// In Wayland, the shell_surface should resize based on the Vulkan surface automagically
120128
}
121129
}
@@ -220,9 +228,26 @@ void vkDisplayWayland::registry_handle_global(void *data, wl_registry *registry,
220228
} else if (strcmp(interface, "wl_seat") == 0) {
221229
display->m_seat = (wl_seat *)wl_registry_bind(registry, id, &wl_seat_interface, 1);
222230
wl_seat_add_listener(display->m_seat, &seat_listener, display);
231+
} else if (strcmp(interface, "wl_output") == 0) {
232+
display->m_output = (wl_output *)wl_registry_bind(registry, id, &wl_output_interface, 1);
233+
wl_output_add_listener(display->m_output, &output_listener, display);
223234
}
224235
}
225236

226237
void vkDisplayWayland::registry_handle_global_remove(void *data, wl_registry *registry, uint32_t name) {}
227238

228-
struct wl_registry_listener vkDisplayWayland::registry_listener;
239+
struct wl_registry_listener vkDisplayWayland::registry_listener;
240+
241+
void vkDisplayWayland::output_handle_geometry(void *data, struct wl_output *wl_output, int x, int y, int physical_width,
242+
int physical_height, int subpixel, const char *make, const char *model,
243+
int transform) {}
244+
245+
void vkDisplayWayland::output_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags, int width, int height,
246+
int refresh) {
247+
auto *display = (vkDisplayWayland *)data;
248+
display->m_screenWidth = width;
249+
display->m_screenHeight = height;
250+
display->m_refresh = refresh;
251+
}
252+
253+
struct wl_output_listener vkDisplayWayland::output_listener;

vktrace/vktrace_replay/vkreplay_vkdisplay_xcb.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
*/
2121

2222
#include "vkreplay_vkdisplay.h"
23+
#include <xcb/randr.h>
24+
#include <xcb/xcb_ewmh.h>
2325

2426
extern "C" {
2527
__attribute__((visibility("default"))) vkDisplayXcb *CreateVkDisplayXcb() { return new vkDisplayXcb(); }
@@ -69,9 +71,33 @@ int vkDisplayXcb::create_window(const unsigned int width, const unsigned int hei
6971
value_list[0] = m_pXcbScreen->black_pixel;
7072
value_list[1] = XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_EXPOSURE;
7173

74+
m_windowWidth = width;
75+
m_windowHeight = height;
76+
7277
xcb_create_window(m_pXcbConnection, XCB_COPY_FROM_PARENT, m_XcbWindow, m_pXcbScreen->root, 0, 0, width, height, 0,
7378
XCB_WINDOW_CLASS_INPUT_OUTPUT, m_pXcbScreen->root_visual, value_mask, value_list);
7479

80+
// Magic code to get screen size
81+
xcb_randr_get_screen_resources_cookie_t screenResCookie;
82+
xcb_randr_crtc_t *pCRTC;
83+
xcb_randr_get_crtc_info_cookie_t crtcResCookie;
84+
xcb_flush(m_pXcbConnection);
85+
screenResCookie = xcb_randr_get_screen_resources(m_pXcbConnection, m_XcbWindow);
86+
xcb_randr_get_screen_resources_reply_t *screenResReply;
87+
screenResReply = xcb_randr_get_screen_resources_reply(m_pXcbConnection, screenResCookie, 0);
88+
if (screenResReply)
89+
pCRTC = xcb_randr_get_screen_resources_crtcs(screenResReply);
90+
else
91+
return -1;
92+
crtcResCookie = xcb_randr_get_crtc_info(m_pXcbConnection, *pCRTC, 0);
93+
xcb_randr_get_crtc_info_reply_t *crtcResReply;
94+
crtcResReply = xcb_randr_get_crtc_info_reply(m_pXcbConnection, crtcResCookie, 0);
95+
if (crtcResReply) {
96+
m_screenWidth = crtcResReply->width;
97+
m_screenHeight = crtcResReply->height;
98+
} else
99+
return -1;
100+
75101
// Magic code that will send notification when window is destroyed
76102
xcb_intern_atom_cookie_t cookie = xcb_intern_atom(m_pXcbConnection, 1, 12, "WM_PROTOCOLS");
77103
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(m_pXcbConnection, cookie, 0);
@@ -97,6 +123,15 @@ void vkDisplayXcb::resize_window(const unsigned int width, const unsigned int he
97123
if (width != m_windowWidth || height != m_windowHeight) {
98124
m_windowWidth = width;
99125
m_windowHeight = height;
126+
if (width >= m_screenWidth || height >= m_screenHeight) {
127+
// Magic code that makes window full screen
128+
xcb_ewmh_connection_t EWMH;
129+
xcb_intern_atom_cookie_t *EWMHCookie = xcb_ewmh_init_atoms(m_pXcbConnection, &EWMH);
130+
xcb_ewmh_init_atoms_replies(&EWMH, EWMHCookie, NULL);
131+
xcb_change_property(m_pXcbConnection, XCB_PROP_MODE_REPLACE, m_XcbWindow, EWMH._NET_WM_STATE, XCB_ATOM_ATOM, 32, 1,
132+
&(EWMH._NET_WM_STATE_FULLSCREEN));
133+
}
134+
100135
uint32_t values[2];
101136
values[0] = width;
102137
values[1] = height;

vktrace/vktrace_replay/vkreplay_vkreplay.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3442,6 +3442,12 @@ VkResult vkReplay::manually_replay_vkQueuePresentKHR(packet_vkQueuePresentKHR *p
34423442
VKTRACE_DELETE(pRemappedSwapchains);
34433443
}
34443444

3445+
if (pPacket->result != VK_SUCCESS) {
3446+
// The call failed during tracing, probably because the window was resized by the app.
3447+
// We'll return the result from the trace file, even though the call succeeded.
3448+
return pPacket->result;
3449+
}
3450+
34453451
return replayResult;
34463452
}
34473453

vktrace/vktrace_replay/vkreplay_window.h

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ extern "C" {
4242
#endif
4343

4444
/* classes to abstract the display and initialization of rendering API for presenting
45-
* framebuffers for display into a window on the screen or else fullscreen.
45+
* framebuffers for display into a window on the screen.
4646
* Uses Bridge design pattern.
4747
*/
4848
namespace vktrace_replay {
@@ -67,13 +67,12 @@ class ReplayDisplayImp {
6767

6868
class ReplayDisplay {
6969
public:
70-
ReplayDisplay() : m_imp(NULL), m_width(0), m_height(0), m_gpu(0), m_fullscreen(false) {}
70+
ReplayDisplay() : m_imp(NULL), m_width(0), m_height(0), m_gpu(0) {}
7171

72-
ReplayDisplay(const unsigned int width, const unsigned int height, const unsigned int gpu, const bool fullscreen)
73-
: m_imp(NULL), m_width(width), m_height(height), m_gpu(gpu), m_fullscreen(fullscreen) {}
72+
ReplayDisplay(const unsigned int width, const unsigned int height, const unsigned int gpu)
73+
: m_imp(NULL), m_width(width), m_height(height), m_gpu(gpu) {}
7474

75-
ReplayDisplay(const unsigned int width, const unsigned int height, const bool fullscreen)
76-
: m_imp(NULL), m_width(width), m_height(height), m_gpu(-1), m_fullscreen(fullscreen) {}
75+
ReplayDisplay(const unsigned int width, const unsigned int height) : m_imp(NULL), m_width(width), m_height(height), m_gpu(-1) {}
7776

7877
virtual ~ReplayDisplay() {}
7978

@@ -99,7 +98,6 @@ class ReplayDisplay {
9998
unsigned int get_gpu() { return m_gpu; }
10099
unsigned int get_width() { return m_width; }
101100
unsigned int get_height() { return m_height; }
102-
bool get_fullscreen() { return m_fullscreen; }
103101
bool get_pause_status() {
104102
if (m_imp) {
105103
return m_imp->get_pause_status();
@@ -124,7 +122,6 @@ class ReplayDisplay {
124122
unsigned int m_width;
125123
unsigned int m_height;
126124
unsigned int m_gpu;
127-
bool m_fullscreen;
128125
};
129126

130127
} // namespace vktrace_replay

0 commit comments

Comments
 (0)