Skip to content

Commit 6566d90

Browse files
authored
Improve Vulkan demo (#717)
* demo: fix errors and warnings in GLFW Vulkan demo * demo: improve resize handling in GLFW Vulkan demo On my machine (x86_64 Linux, Wayland) VK_SUBOPTIMAL or VK_OUT_OF_DATE_KHR were never returned so the resizing of the swapchain never happened. Fix by using GLFW's resize callback to detect a window resize and a swapchain recreation. Vulkan tutorial uses the same approach. fb_scale was never used in the Vulkan backend, so it was removed. * demo: fix copy&paste typo in GLFW Vulkan demo * demo: sync nuklear_glfw_vulkan.in.h with nuklear_glfw_vulkan.h Over time people have not been noticing that the expected workflow is to build nuklear_glfw_vulkan.h from nuklear_glfw_vulkan.in.h
1 parent b2ffce5 commit 6566d90

File tree

3 files changed

+50
-19
lines changed

3 files changed

+50
-19
lines changed

demo/glfw_vulkan/main.c

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,19 @@ struct vulkan_demo {
139139
VkDeviceMemory demo_texture_memory;
140140

141141
VkFence render_fence;
142+
143+
bool framebuffer_resized;
142144
};
143145

146+
static void glfw_framebuffer_resize_callback(GLFWwindow* window, int width, int height) {
147+
struct vulkan_demo* demo;
148+
149+
(void)width;
150+
(void)height;
151+
demo = glfwGetWindowUserPointer(window);
152+
demo->framebuffer_resized = true;
153+
}
154+
144155
static void glfw_error_callback(int e, const char *d) {
145156
fprintf(stderr, "Error %d: %s\n", e, d);
146157
}
@@ -299,7 +310,7 @@ bool create_instance(struct vulkan_demo *demo) {
299310
if (i > 0) {
300311
printf(", ");
301312
}
302-
printf(enabled_extensions[i]);
313+
printf("%s\n", enabled_extensions[i]);
303314
}
304315
printf("\n");
305316
for (i = 0; i < enabled_extension_count; i++) {
@@ -1227,8 +1238,8 @@ bool create_graphics_pipeline(struct vulkan_demo *demo) {
12271238
bool ret = false;
12281239
char *vert_shader_code = NULL;
12291240
char *frag_shader_code = NULL;
1230-
VkShaderModule vert_shader_module;
1231-
VkShaderModule frag_shader_module;
1241+
VkShaderModule vert_shader_module = VK_NULL_HANDLE;
1242+
VkShaderModule frag_shader_module = VK_NULL_HANDLE;
12321243
FILE *fp;
12331244
size_t file_len;
12341245
VkPipelineShaderStageCreateInfo vert_shader_stage_info;
@@ -1246,8 +1257,9 @@ bool create_graphics_pipeline(struct vulkan_demo *demo) {
12461257
VkPipelineLayoutCreateInfo pipeline_layout_info;
12471258
VkResult result;
12481259
VkGraphicsPipelineCreateInfo pipeline_info;
1260+
size_t read_result;
12491261

1250-
fp = fopen("shaders/demo.vert.spv", "r");
1262+
fp = fopen("shaders/demo.vert.spv", "rb");
12511263
if (!fp) {
12521264
fprintf(stderr, "Couldn't open shaders/demo.vert.spv\n");
12531265
return false;
@@ -1256,15 +1268,19 @@ bool create_graphics_pipeline(struct vulkan_demo *demo) {
12561268
file_len = ftell(fp);
12571269
vert_shader_code = malloc(file_len);
12581270
fseek(fp, 0, 0);
1259-
fread(vert_shader_code, 1, file_len, fp);
1271+
read_result = fread(vert_shader_code, file_len, 1, fp);
12601272
fclose(fp);
1273+
if (read_result != 1) {
1274+
fprintf(stderr, "Could not read fragment shader\n");
1275+
goto cleanup;
1276+
}
12611277

12621278
if (!create_shader_module(demo->device, vert_shader_code, file_len,
12631279
&vert_shader_module)) {
12641280
goto cleanup;
12651281
}
12661282

1267-
fp = fopen("shaders/demo.frag.spv", "r");
1283+
fp = fopen("shaders/demo.frag.spv", "rb");
12681284
if (!fp) {
12691285
fprintf(stderr, "Couldn't open shaders/demo.frag.spv\n");
12701286
return false;
@@ -1273,8 +1289,12 @@ bool create_graphics_pipeline(struct vulkan_demo *demo) {
12731289
file_len = ftell(fp);
12741290
frag_shader_code = malloc(file_len);
12751291
fseek(fp, 0, 0);
1276-
fread(frag_shader_code, 1, file_len, fp);
1292+
read_result = fread(frag_shader_code, file_len, 1, fp);
12771293
fclose(fp);
1294+
if (read_result != 1) {
1295+
fprintf(stderr, "Could not read fragment shader\n");
1296+
goto cleanup;
1297+
}
12781298

12791299
if (!create_shader_module(demo->device, frag_shader_code, file_len,
12801300
&frag_shader_module)) {
@@ -1862,6 +1882,8 @@ bool create_vulkan_demo(struct vulkan_demo *demo) {
18621882
return false;
18631883
}
18641884

1885+
demo->framebuffer_resized = false;
1886+
18651887
return true;
18661888
}
18671889

@@ -1876,6 +1898,9 @@ bool recreate_swap_chain(struct vulkan_demo *demo) {
18761898
update_descriptor_sets(demo);
18771899
nk_glfw3_resize(demo->swap_chain_image_extent.width,
18781900
demo->swap_chain_image_extent.height);
1901+
1902+
demo->framebuffer_resized = false;
1903+
18791904
return true;
18801905
}
18811906

@@ -1961,7 +1986,7 @@ bool render(struct vulkan_demo *demo, struct nk_colorf *bg,
19611986

19621987
result = vkQueuePresentKHR(demo->present_queue, &present_info);
19631988

1964-
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) {
1989+
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || demo->framebuffer_resized) {
19651990
recreate_swap_chain(demo);
19661991
} else if (result != VK_SUCCESS) {
19671992
fprintf(stderr, "vkQueuePresentKHR failed: %d\n", result);
@@ -2073,6 +2098,8 @@ int main(void) {
20732098
memset(&demo, 0, sizeof(struct vulkan_demo));
20742099
demo.win =
20752100
glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Demo", NULL, NULL);
2101+
glfwSetWindowUserPointer(demo.win, &demo);
2102+
glfwSetFramebufferSizeCallback(demo.win, glfw_framebuffer_resize_callback);
20762103

20772104
if (!create_vulkan_demo(&demo)) {
20782105
fprintf(stderr, "failed to create vulkan demo!\n");
@@ -2192,6 +2219,10 @@ int main(void) {
21922219
demo.image_available, NULL, &image_index);
21932220

21942221
if (result == VK_ERROR_OUT_OF_DATE_KHR) {
2222+
recreate_swap_chain(&demo);
2223+
2224+
/* If vkAcquireNextImageKHR does not successfully acquire an image,
2225+
* semaphore and fence are unaffected. */
21952226
continue;
21962227
}
21972228
if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {

demo/glfw_vulkan/nuklear_glfw_vulkan.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,6 @@ static struct nk_glfw {
372372
struct nk_glfw_device vulkan;
373373
struct nk_context ctx;
374374
struct nk_font_atlas atlas;
375-
struct nk_vec2 fb_scale;
376375
unsigned int text[NK_GLFW_TEXT_MAX];
377376
int text_len;
378377
struct nk_vec2 scroll;
@@ -1179,8 +1178,6 @@ NK_API void nk_glfw3_resize(uint32_t framebuffer_width,
11791178
struct nk_glfw_device *dev = &glfw.vulkan;
11801179
glfwGetWindowSize(glfw.win, &glfw.width, &glfw.height);
11811180
glfwGetFramebufferSize(glfw.win, &glfw.display_width, &glfw.display_height);
1182-
glfw.fb_scale.x = (float)glfw.display_width / (float)glfw.width;
1183-
glfw.fb_scale.y = (float)glfw.display_height / (float)glfw.height;
11841181

11851182
nk_glfw3_destroy_render_resources(dev);
11861183
nk_glfw3_create_render_resources(dev, framebuffer_width,
@@ -1264,7 +1261,7 @@ NK_API void nk_glfw3_new_frame(void) {
12641261
for (i = 0; i < glfw.text_len; ++i)
12651262
nk_input_unicode(ctx, glfw.text[i]);
12661263

1267-
#ifdef NK_GLFW_GL4_MOUSE_GRABBING
1264+
#ifdef NK_GLFW_VULKAN_MOUSE_GRABBING
12681265
/* optional grabbing behavior */
12691266
if (ctx->input.mouse.grab)
12701267
glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
@@ -1332,7 +1329,7 @@ NK_API void nk_glfw3_new_frame(void) {
13321329

13331330
glfwGetCursorPos(win, &x, &y);
13341331
nk_input_motion(ctx, (int)x, (int)y);
1335-
#ifdef NK_GLFW_GL4_MOUSE_GRABBING
1332+
#ifdef NK_GLFW_VULKAN_MOUSE_GRABBING
13361333
if (ctx->input.mouse.grabbed) {
13371334
glfwSetCursorPos(glfw.win, ctx->input.mouse.prev.x,
13381335
ctx->input.mouse.prev.y);

demo/glfw_vulkan/src/nuklear_glfw_vulkan.in.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ unsigned char nuklearshaders_nuklear_frag_spv[] = {};
2424
unsigned int nuklearshaders_nuklear_frag_spv_len = 0;
2525
// NUKLEAR_SHADERS_END
2626

27+
#include <assert.h>
2728
#include <stddef.h>
2829
#include <string.h>
2930
#define GLFW_INCLUDE_VULKAN
@@ -71,7 +72,6 @@ NK_API void nk_glfw3_mouse_button_callback(GLFWwindow *win, int button,
7172
*/
7273
#ifdef NK_GLFW_VULKAN_IMPLEMENTATION
7374
#undef NK_GLFW_VULKAN_IMPLEMENTATION
74-
#include <assert.h>
7575
#include <stdlib.h>
7676

7777
#ifndef NK_GLFW_TEXT_MAX
@@ -149,13 +149,13 @@ static struct nk_glfw {
149149
struct nk_glfw_device vulkan;
150150
struct nk_context ctx;
151151
struct nk_font_atlas atlas;
152-
struct nk_vec2 fb_scale;
153152
unsigned int text[NK_GLFW_TEXT_MAX];
154153
int text_len;
155154
struct nk_vec2 scroll;
156155
double last_button_click;
157156
int is_double_click_down;
158157
struct nk_vec2 double_click_pos;
158+
float delta_time_seconds_last;
159159
} glfw;
160160

161161
struct Mat4f {
@@ -955,8 +955,6 @@ NK_API void nk_glfw3_resize(uint32_t framebuffer_width,
955955
struct nk_glfw_device *dev = &glfw.vulkan;
956956
glfwGetWindowSize(glfw.win, &glfw.width, &glfw.height);
957957
glfwGetFramebufferSize(glfw.win, &glfw.display_width, &glfw.display_height);
958-
glfw.fb_scale.x = (float)glfw.display_width / (float)glfw.width;
959-
glfw.fb_scale.y = (float)glfw.display_height / (float)glfw.height;
960958

961959
nk_glfw3_destroy_render_resources(dev);
962960
nk_glfw3_create_render_resources(dev, framebuffer_width,
@@ -1031,11 +1029,16 @@ NK_API void nk_glfw3_new_frame(void) {
10311029
struct nk_context *ctx = &glfw.ctx;
10321030
struct GLFWwindow *win = glfw.win;
10331031

1032+
/* update the timer */
1033+
float delta_time_now = (float)glfwGetTime();
1034+
glfw.ctx.delta_time_seconds = delta_time_now - glfw.delta_time_seconds_last;
1035+
glfw.delta_time_seconds_last = delta_time_now;
1036+
10341037
nk_input_begin(ctx);
10351038
for (i = 0; i < glfw.text_len; ++i)
10361039
nk_input_unicode(ctx, glfw.text[i]);
10371040

1038-
#ifdef NK_GLFW_GL4_MOUSE_GRABBING
1041+
#ifdef NK_GLFW_VULKAN_MOUSE_GRABBING
10391042
/* optional grabbing behavior */
10401043
if (ctx->input.mouse.grab)
10411044
glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
@@ -1103,7 +1106,7 @@ NK_API void nk_glfw3_new_frame(void) {
11031106

11041107
glfwGetCursorPos(win, &x, &y);
11051108
nk_input_motion(ctx, (int)x, (int)y);
1106-
#ifdef NK_GLFW_GL4_MOUSE_GRABBING
1109+
#ifdef NK_GLFW_VULKAN_MOUSE_GRABBING
11071110
if (ctx->input.mouse.grabbed) {
11081111
glfwSetCursorPos(glfw.win, ctx->input.mouse.prev.x,
11091112
ctx->input.mouse.prev.y);

0 commit comments

Comments
 (0)