/*
- * Copyright (c) 2015-2016 The Khronos Group Inc.
- * Copyright (c) 2015-2016 Valve Corporation
- * Copyright (c) 2015-2016 LunarG, Inc.
+ * Copyright (c) 2015-2019 The Khronos Group Inc.
+ * Copyright (c) 2015-2019 Valve Corporation
+ * Copyright (c) 2015-2019 LunarG, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#define APP_NAME_STR_LEN 80
#endif // _WIN32
-#if defined(VK_USE_PLATFORM_MIR_KHR)
-#warning "Cube does not have code for Mir at this time"
-#endif
-
#ifdef ANDROID
#include "vulkan_wrapper.h"
#else
#define BILLION 1000000000L
#define DEMO_TEXTURE_COUNT 1
-#define APP_SHORT_NAME "cube"
-#define APP_LONG_NAME "The Vulkan Cube Demo Program"
+#define APP_SHORT_NAME "vkcube"
+#define APP_LONG_NAME "Vulkan Cube"
// Allow a maximum of two outstanding presentation operations.
#define FRAME_LAG 2
void DbgMsg(char *fmt, ...) {
va_list va;
va_start(va, fmt);
- printf(fmt, va);
- fflush(stdout);
+ vprintf(fmt, va);
va_end(va);
+ fflush(stdout);
}
#elif defined __ANDROID__
#include <android/log.h>
-#define ERR_EXIT(err_msg, err_class) \
- do { \
- ((void)__android_log_print(ANDROID_LOG_INFO, "Cube", err_msg)); \
- exit(1); \
+#define ERR_EXIT(err_msg, err_class) \
+ do { \
+ ((void)__android_log_print(ANDROID_LOG_INFO, "Vulkan Cube", err_msg)); \
+ exit(1); \
} while (0)
#ifdef VARARGS_WORKS_ON_ANDROID
void DbgMsg(const char *fmt, ...) {
va_list va;
va_start(va, fmt);
- __android_log_print(ANDROID_LOG_INFO, "Cube", fmt, va);
+ __android_log_print(ANDROID_LOG_INFO, "Vulkan Cube", fmt, va);
va_end(va);
}
#else // VARARGS_WORKS_ON_ANDROID
-#define DbgMsg(fmt, ...) \
- do { \
- ((void)__android_log_print(ANDROID_LOG_INFO, "Cube", fmt, ##__VA_ARGS__)); \
+#define DbgMsg(fmt, ...) \
+ do { \
+ ((void)__android_log_print(ANDROID_LOG_INFO, "Vulkan Cube", fmt, ##__VA_ARGS__)); \
} while (0)
#endif // VARARGS_WORKS_ON_ANDROID
#else
void DbgMsg(char *fmt, ...) {
va_list va;
va_start(va, fmt);
- printf(fmt, va);
- fflush(stdout);
+ vprintf(fmt, va);
va_end(va);
+ fflush(stdout);
}
#endif
VkImageView view;
VkBuffer uniform_buffer;
VkDeviceMemory uniform_memory;
+ void *uniform_memory_ptr;
VkFramebuffer framebuffer;
VkDescriptorSet descriptor_set;
} SwapchainImageResources;
struct wl_seat *seat;
struct wl_pointer *pointer;
struct wl_keyboard *keyboard;
-#elif defined(VK_USE_PLATFORM_MIR_KHR)
#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
struct ANativeWindow *window;
-#elif (defined(VK_USE_PLATFORM_IOS_MVK) || defined(VK_USE_PLATFORM_MACOS_MVK))
- void *window;
+#elif defined(VK_USE_PLATFORM_METAL_EXT)
+ void *caMetalLayer;
#endif
VkSurfaceKHR surface;
bool prepared;
#ifdef _WIN32
in_callback = true;
- if (!demo->suppress_popups)
- MessageBox(NULL, message, "Alert", MB_OK);
+ if (!demo->suppress_popups) MessageBox(NULL, message, "Alert", MB_OK);
in_callback = false;
#elif defined(ANDROID)
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) {
- __android_log_print(ANDROID_LOG_INFO, APP_SHORT_NAME, "%s", message);
+ __android_log_print(ANDROID_LOG_INFO, APP_SHORT_NAME, "%s", message);
} else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
- __android_log_print(ANDROID_LOG_WARN, APP_SHORT_NAME, "%s", message);
+ __android_log_print(ANDROID_LOG_WARN, APP_SHORT_NAME, "%s", message);
} else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
__android_log_print(ANDROID_LOG_ERROR, APP_SHORT_NAME, "%s", message);
} else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) {
__android_log_print(ANDROID_LOG_VERBOSE, APP_SHORT_NAME, "%s", message);
} else {
- __android_log_print(ANDROID_LOG_INFO, APP_SHORT_NAME, "%s", message);
+ __android_log_print(ANDROID_LOG_INFO, APP_SHORT_NAME, "%s", message);
}
#else
return false;
}
-// Forward declaration:
+// Forward declarations:
static void demo_resize(struct demo *demo);
+static void demo_create_surface(struct demo *demo);
static bool memory_type_from_properties(struct demo *demo, uint32_t typeBits, VkFlags requirements_mask, uint32_t *typeIndex) {
// Search memtypes to find first index with those properties
&demo->swapchain_image_resources[demo->current_buffer].descriptor_set, 0, NULL);
VkViewport viewport;
memset(&viewport, 0, sizeof(viewport));
- viewport.height = (float)demo->height;
- viewport.width = (float)demo->width;
+ float viewport_dimension;
+ if (demo->width < demo->height) {
+ viewport_dimension = (float)demo->width;
+ viewport.y = (demo->height - demo->width) / 2.0f;
+ } else {
+ viewport_dimension = (float)demo->height;
+ viewport.x = (demo->width - demo->height) / 2.0f;
+ }
+ viewport.height = viewport_dimension;
+ viewport.width = viewport_dimension;
viewport.minDepth = (float)0.0f;
viewport.maxDepth = (float)1.0f;
vkCmdSetViewport(cmd_buf, 0, 1, &viewport);
void demo_update_data_buffer(struct demo *demo) {
mat4x4 MVP, Model, VP;
int matrixSize = sizeof(MVP);
- uint8_t *pData;
- VkResult U_ASSERT_ONLY err;
mat4x4_mul(VP, demo->projection_matrix, demo->view_matrix);
mat4x4_rotate(demo->model_matrix, Model, 0.0f, 1.0f, 0.0f, (float)degreesToRadians(demo->spin_angle));
mat4x4_mul(MVP, VP, demo->model_matrix);
- err = vkMapMemory(demo->device, demo->swapchain_image_resources[demo->current_buffer].uniform_memory, 0, VK_WHOLE_SIZE, 0,
- (void **)&pData);
- assert(!err);
-
- memcpy(pData, (const void *)&MVP[0][0], matrixSize);
-
- vkUnmapMemory(demo->device, demo->swapchain_image_resources[demo->current_buffer].uniform_memory);
+ memcpy(demo->swapchain_image_resources[demo->current_buffer].uniform_memory_ptr, (const void *)&MVP[0][0], matrixSize);
}
void DemoUpdateTargetIPD(struct demo *demo) {
// demo->swapchain is not as optimal as it could be, but the platform's
// presentation engine will still present the image correctly.
break;
+ } else if (err == VK_ERROR_SURFACE_LOST_KHR) {
+ vkDestroySurfaceKHR(demo->inst, demo->surface, NULL);
+ demo_create_surface(demo);
+ demo_resize(demo);
} else {
assert(!err);
}
.pImageIndices = &demo->current_buffer,
};
+ VkRectLayerKHR rect;
+ VkPresentRegionKHR region;
+ VkPresentRegionsKHR regions;
if (demo->VK_KHR_incremental_present_enabled) {
// If using VK_KHR_incremental_present, we provide a hint of the region
// that contains changed content relative to the previously-presented
// ensure that the entire image has the correctly-drawn content.
uint32_t eighthOfWidth = demo->width / 8;
uint32_t eighthOfHeight = demo->height / 8;
- VkRectLayerKHR rect = {
- .offset.x = eighthOfWidth,
- .offset.y = eighthOfHeight,
- .extent.width = eighthOfWidth * 6,
- .extent.height = eighthOfHeight * 6,
- .layer = 0,
- };
- VkPresentRegionKHR region = {
- .rectangleCount = 1,
- .pRectangles = &rect,
- };
- VkPresentRegionsKHR regions = {
- .sType = VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR,
- .pNext = present.pNext,
- .swapchainCount = present.swapchainCount,
- .pRegions = ®ion,
- };
+
+ rect.offset.x = eighthOfWidth;
+ rect.offset.y = eighthOfHeight;
+ rect.extent.width = eighthOfWidth * 6;
+ rect.extent.height = eighthOfHeight * 6;
+ rect.layer = 0;
+
+ region.rectangleCount = 1;
+ region.pRectangles = ▭
+
+ regions.sType = VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR;
+ regions.pNext = present.pNext;
+ regions.swapchainCount = present.swapchainCount;
+ regions.pRegions = ®ion;
present.pNext = ®ions;
}
} else if (err == VK_SUBOPTIMAL_KHR) {
// demo->swapchain is not as optimal as it could be, but the platform's
// presentation engine will still present the image correctly.
+ } else if (err == VK_ERROR_SURFACE_LOST_KHR) {
+ vkDestroySurfaceKHR(demo->inst, demo->surface, NULL);
+ demo_create_surface(demo);
+ demo_resize(demo);
} else {
assert(!err);
}
demo->next_present_id = 1;
}
+ if (NULL != swapchainImages) {
+ free(swapchainImages);
+ }
+
if (NULL != presentModes) {
free(presentModes);
}
VkBufferCreateInfo buf_info;
VkMemoryRequirements mem_reqs;
VkMemoryAllocateInfo mem_alloc;
- uint8_t *pData;
mat4x4 MVP, VP;
VkResult U_ASSERT_ONLY err;
bool U_ASSERT_ONLY pass;
err = vkAllocateMemory(demo->device, &mem_alloc, NULL, &demo->swapchain_image_resources[i].uniform_memory);
assert(!err);
- err = vkMapMemory(demo->device, demo->swapchain_image_resources[i].uniform_memory, 0, VK_WHOLE_SIZE, 0, (void **)&pData);
+ err = vkMapMemory(demo->device, demo->swapchain_image_resources[i].uniform_memory, 0, VK_WHOLE_SIZE, 0,
+ &demo->swapchain_image_resources[i].uniform_memory_ptr);
assert(!err);
- memcpy(pData, &data, sizeof data);
-
- vkUnmapMemory(demo->device, demo->swapchain_image_resources[i].uniform_memory);
+ memcpy(demo->swapchain_image_resources[i].uniform_memory_ptr, &data, sizeof data);
err = vkBindBufferMemory(demo->device, demo->swapchain_image_resources[i].uniform_buffer,
demo->swapchain_image_resources[i].uniform_memory, 0);
.preserveAttachmentCount = 0,
.pPreserveAttachments = NULL,
};
+
+ VkSubpassDependency attachmentDependencies[2] = {
+ [0] =
+ {
+ // Depth buffer is shared between swapchain images
+ .srcSubpass = VK_SUBPASS_EXTERNAL,
+ .dstSubpass = 0,
+ .srcStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
+ .dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
+ .srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
+ .dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
+ .dependencyFlags = 0,
+ },
+ [1] =
+ {
+ // Image Layout Transition
+ .srcSubpass = VK_SUBPASS_EXTERNAL,
+ .dstSubpass = 0,
+ .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ .srcAccessMask = 0,
+ .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
+ .dependencyFlags = 0,
+ },
+ };
+
const VkRenderPassCreateInfo rp_info = {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
.pNext = NULL,
.pAttachments = attachments,
.subpassCount = 1,
.pSubpasses = &subpass,
- .dependencyCount = 0,
- .pDependencies = NULL,
+ .dependencyCount = 2,
+ .pDependencies = attachmentDependencies,
};
VkResult U_ASSERT_ONLY err;
vkDestroyImageView(demo->device, demo->swapchain_image_resources[i].view, NULL);
vkFreeCommandBuffers(demo->device, demo->cmd_pool, 1, &demo->swapchain_image_resources[i].cmd);
vkDestroyBuffer(demo->device, demo->swapchain_image_resources[i].uniform_buffer, NULL);
+ vkUnmapMemory(demo->device, demo->swapchain_image_resources[i].uniform_memory);
vkFreeMemory(demo->device, demo->swapchain_image_resources[i].uniform_memory, NULL);
}
free(demo->swapchain_image_resources);
wl_compositor_destroy(demo->compositor);
wl_registry_destroy(demo->registry);
wl_display_disconnect(demo->display);
-#elif defined(VK_USE_PLATFORM_MIR_KHR)
#endif
vkDestroyInstance(demo->inst, NULL);
vkDestroyImageView(demo->device, demo->swapchain_image_resources[i].view, NULL);
vkFreeCommandBuffers(demo->device, demo->cmd_pool, 1, &demo->swapchain_image_resources[i].cmd);
vkDestroyBuffer(demo->device, demo->swapchain_image_resources[i].uniform_buffer, NULL);
+ vkUnmapMemory(demo->device, demo->swapchain_image_resources[i].uniform_memory);
vkFreeMemory(demo->device, demo->swapchain_image_resources[i].uniform_memory, NULL);
}
vkDestroyCommandPool(demo->device, demo->cmd_pool, NULL);
demo_draw(demo);
demo->curFrame++;
- if (demo->frameCount != INT_MAX && demo->curFrame == demo->frameCount) {
+ if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount) {
PostQuitMessage(validation_error);
}
}
demo_resize(&demo);
}
break;
+ case WM_KEYDOWN:
+ switch (wParam) {
+ case VK_ESCAPE:
+ PostQuitMessage(validation_error);
+ break;
+ case VK_LEFT:
+ demo.spin_angle -= demo.spin_increment;
+ break;
+ case VK_RIGHT:
+ demo.spin_angle += demo.spin_increment;
+ break;
+ case VK_SPACE:
+ demo.pause = !demo.pause;
+ break;
+ }
+ return 0;
default:
break;
}
demo_draw(demo);
demo->curFrame++;
}
-#elif defined(VK_USE_PLATFORM_MACOS_MVK)
+#elif defined(VK_USE_PLATFORM_METAL_EXT)
static void demo_run(struct demo *demo) {
demo_draw(demo);
demo->curFrame++;
demo->quit = TRUE;
}
}
-#elif defined(VK_USE_PLATFORM_MIR_KHR)
#elif defined(VK_USE_PLATFORM_DISPLAY_KHR)
static VkResult demo_create_display_surface(struct demo *demo) {
VkResult U_ASSERT_ONLY err;
VkResult err;
uint32_t instance_extension_count = 0;
uint32_t instance_layer_count = 0;
- uint32_t validation_layer_count = 0;
- char **instance_validation_layers = NULL;
+ char *instance_validation_layers[] = {"VK_LAYER_KHRONOS_validation"};
demo->enabled_extension_count = 0;
demo->enabled_layer_count = 0;
demo->is_minimized = false;
demo->cmd_pool = VK_NULL_HANDLE;
- char *instance_validation_layers_alt1[] = {"VK_LAYER_LUNARG_standard_validation"};
-
- char *instance_validation_layers_alt2[] = {"VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation",
- "VK_LAYER_LUNARG_object_tracker", "VK_LAYER_LUNARG_core_validation",
- "VK_LAYER_GOOGLE_unique_objects"};
-
- /* Look for validation layers */
+ // Look for validation layers
VkBool32 validation_found = 0;
if (demo->validate) {
err = vkEnumerateInstanceLayerProperties(&instance_layer_count, NULL);
assert(!err);
- instance_validation_layers = instance_validation_layers_alt1;
if (instance_layer_count > 0) {
VkLayerProperties *instance_layers = malloc(sizeof(VkLayerProperties) * instance_layer_count);
err = vkEnumerateInstanceLayerProperties(&instance_layer_count, instance_layers);
assert(!err);
- validation_found = demo_check_layers(ARRAY_SIZE(instance_validation_layers_alt1), instance_validation_layers,
+ validation_found = demo_check_layers(ARRAY_SIZE(instance_validation_layers), instance_validation_layers,
instance_layer_count, instance_layers);
if (validation_found) {
- demo->enabled_layer_count = ARRAY_SIZE(instance_validation_layers_alt1);
- demo->enabled_layers[0] = "VK_LAYER_LUNARG_standard_validation";
- validation_layer_count = 1;
- } else {
- // use alternative set of validation layers
- instance_validation_layers = instance_validation_layers_alt2;
- demo->enabled_layer_count = ARRAY_SIZE(instance_validation_layers_alt2);
- validation_found = demo_check_layers(ARRAY_SIZE(instance_validation_layers_alt2), instance_validation_layers,
- instance_layer_count, instance_layers);
- validation_layer_count = ARRAY_SIZE(instance_validation_layers_alt2);
- for (uint32_t i = 0; i < validation_layer_count; i++) {
- demo->enabled_layers[i] = instance_validation_layers[i];
- }
+ demo->enabled_layer_count = ARRAY_SIZE(instance_validation_layers);
+ demo->enabled_layers[0] = "VK_LAYER_KHRONOS_validation";
}
free(instance_layers);
}
platformSurfaceExtFound = 1;
demo->extension_names[demo->enabled_extension_count++] = VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME;
}
-#elif defined(VK_USE_PLATFORM_MIR_KHR)
#elif defined(VK_USE_PLATFORM_DISPLAY_KHR)
if (!strcmp(VK_KHR_DISPLAY_EXTENSION_NAME, instance_extensions[i].extensionName)) {
platformSurfaceExtFound = 1;
platformSurfaceExtFound = 1;
demo->extension_names[demo->enabled_extension_count++] = VK_KHR_ANDROID_SURFACE_EXTENSION_NAME;
}
-#elif defined(VK_USE_PLATFORM_IOS_MVK)
- if (!strcmp(VK_MVK_IOS_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName)) {
+#elif defined(VK_USE_PLATFORM_METAL_EXT)
+ if (!strcmp(VK_EXT_METAL_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName)) {
platformSurfaceExtFound = 1;
- demo->extension_names[demo->enabled_extension_count++] = VK_MVK_IOS_SURFACE_EXTENSION_NAME;
- }
-#elif defined(VK_USE_PLATFORM_MACOS_MVK)
- if (!strcmp(VK_MVK_MACOS_SURFACE_EXTENSION_NAME, instance_extensions[i].extensionName)) {
- platformSurfaceExtFound = 1;
- demo->extension_names[demo->enabled_extension_count++] = VK_MVK_MACOS_SURFACE_EXTENSION_NAME;
+ demo->extension_names[demo->enabled_extension_count++] = VK_EXT_METAL_SURFACE_EXTENSION_NAME;
}
#endif
if (!strcmp(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, instance_extensions[i].extensionName)) {
"Do you have a compatible Vulkan installable client driver (ICD) installed?\n"
"Please look at the Getting Started guide for additional information.\n",
"vkCreateInstance Failure");
-#elif defined(VK_USE_PLATFORM_IOS_MVK)
- ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_MVK_IOS_SURFACE_EXTENSION_NAME
- " extension.\n\n"
- "Do you have a compatible Vulkan installable client driver (ICD) installed?\n"
- "Please look at the Getting Started guide for additional information.\n",
- "vkCreateInstance Failure");
-#elif defined(VK_USE_PLATFORM_MACOS_MVK)
- ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_MVK_MACOS_SURFACE_EXTENSION_NAME
+#elif defined(VK_USE_PLATFORM_METAL_EXT)
+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_EXT_METAL_SURFACE_EXTENSION_NAME
" extension.\n\n"
"Do you have a compatible Vulkan installable client driver (ICD) installed?\n"
"Please look at the Getting Started guide for additional information.\n",
"Do you have a compatible Vulkan installable client driver (ICD) installed?\n"
"Please look at the Getting Started guide for additional information.\n",
"vkCreateInstance Failure");
-#elif defined(VK_USE_PLATFORM_MIR_KHR)
#elif defined(VK_USE_PLATFORM_DISPLAY_KHR)
ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find the " VK_KHR_DISPLAY_EXTENSION_NAME
" extension.\n\n"
assert(!err);
}
-static void demo_init_vk_swapchain(struct demo *demo) {
+static void demo_create_surface(struct demo *demo) {
VkResult U_ASSERT_ONLY err;
// Create a WSI surface for the window:
createInfo.surface = demo->window;
err = vkCreateWaylandSurfaceKHR(demo->inst, &createInfo, NULL, &demo->surface);
-#elif defined(VK_USE_PLATFORM_MIR_KHR)
#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
VkAndroidSurfaceCreateInfoKHR createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
err = vkCreateXcbSurfaceKHR(demo->inst, &createInfo, NULL, &demo->surface);
#elif defined(VK_USE_PLATFORM_DISPLAY_KHR)
err = demo_create_display_surface(demo);
-#elif defined(VK_USE_PLATFORM_IOS_MVK)
- VkIOSSurfaceCreateInfoMVK surface;
- surface.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK;
+#elif defined(VK_USE_PLATFORM_METAL_EXT)
+ VkMetalSurfaceCreateInfoEXT surface;
+ surface.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT;
surface.pNext = NULL;
surface.flags = 0;
- surface.pView = demo->window;
+ surface.pLayer = demo->caMetalLayer;
- err = vkCreateIOSSurfaceMVK(demo->inst, &surface, NULL, &demo->surface);
-#elif defined(VK_USE_PLATFORM_MACOS_MVK)
- VkMacOSSurfaceCreateInfoMVK surface;
- surface.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
- surface.pNext = NULL;
- surface.flags = 0;
- surface.pView = demo->window;
-
- err = vkCreateMacOSSurfaceMVK(demo->inst, &surface, NULL, &demo->surface);
+ err = vkCreateMetalSurfaceEXT(demo->inst, &surface, NULL, &demo->surface);
#endif
assert(!err);
+}
+
+static void demo_init_vk_swapchain(struct demo *demo) {
+ VkResult U_ASSERT_ONLY err;
+
+ demo_create_surface(demo);
// Iterate over each queue to learn whether it supports presenting:
VkBool32 *supportsPresent = (VkBool32 *)malloc(demo->queue_family_count * sizeof(VkBool32));
VkSurfaceFormatKHR *surfFormats = (VkSurfaceFormatKHR *)malloc(formatCount * sizeof(VkSurfaceFormatKHR));
err = demo->fpGetPhysicalDeviceSurfaceFormatsKHR(demo->gpu, demo->surface, &formatCount, surfFormats);
assert(!err);
- // If the format list includes just one entry of VK_FORMAT_UNDEFINED,
- // the surface has no preferred format. Otherwise, at least one
- // supported format will be returned.
- if (formatCount == 1 && surfFormats[0].format == VK_FORMAT_UNDEFINED) {
- demo->format = VK_FORMAT_B8G8R8A8_UNORM;
- } else {
- assert(formatCount >= 1);
- demo->format = surfFormats[0].format;
- }
+ assert(formatCount >= 1);
+ demo->format = surfFormats[0].format;
demo->color_space = surfFormats[0].colorSpace;
+ free(surfFormats);
demo->quit = false;
demo->curFrame = 0;
seat_handle_capabilities,
};
-static void registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface,
- uint32_t version UNUSED) {
+static void registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version) {
struct demo *demo = data;
// pickup wayland objects when they appear
if (strcmp(interface, "wl_compositor") == 0) {
- demo->compositor = wl_registry_bind(registry, id, &wl_compositor_interface, 1);
+ uint32_t minVersion = version < 4 ? version : 4;
+ demo->compositor = wl_registry_bind(registry, id, &wl_compositor_interface, minVersion);
+ if (demo->VK_KHR_incremental_present_enabled && minVersion < 4) {
+ fprintf(stderr, "Wayland compositor doesn't support VK_KHR_incremental_present, disabling.\n");
+ demo->VK_KHR_incremental_present_enabled = false;
+ }
} else if (strcmp(interface, "wl_shell") == 0) {
demo->shell = wl_registry_bind(registry, id, &wl_shell_interface, 1);
} else if (strcmp(interface, "wl_seat") == 0) {
static void registry_handle_global_remove(void *data UNUSED, struct wl_registry *registry UNUSED, uint32_t name UNUSED) {}
static const struct wl_registry_listener registry_listener = {registry_handle_global, registry_handle_global_remove};
-#elif defined(VK_USE_PLATFORM_MIR_KHR)
#endif
static void demo_init_connection(struct demo *demo) {
demo->registry = wl_display_get_registry(demo->display);
wl_registry_add_listener(demo->registry, ®istry_listener, demo);
wl_display_dispatch(demo->display);
-#elif defined(VK_USE_PLATFORM_MIR_KHR)
#endif
}
}
#if defined(ANDROID)
- ERR_EXIT("Usage: cube [--validate]\n", "Usage");
+ ERR_EXIT("Usage: vkcube [--validate]\n", "Usage");
#else
- fprintf(stderr,
- "Usage:\n %s\t[--use_staging] [--validate] [--validate-checks-disabled] [--break]\n"
- "\t[--c <framecount>] [--suppress_popups] [--incremental_present] [--display_timing]\n"
- "\t[--present_mode <present mode enum>]\n"
- "\t <present_mode_enum>\tVK_PRESENT_MODE_IMMEDIATE_KHR = %d\n"
- "\t\t\t\tVK_PRESENT_MODE_MAILBOX_KHR = %d\n"
- "\t\t\t\tVK_PRESENT_MODE_FIFO_KHR = %d\n"
- "\t\t\t\tVK_PRESENT_MODE_FIFO_RELAXED_KHR = %d\n",
- APP_SHORT_NAME, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_FIFO_KHR,
- VK_PRESENT_MODE_FIFO_RELAXED_KHR);
+ char *message =
+ "Usage:\n %s\t[--use_staging] [--validate] [--validate-checks-disabled]\n"
+ "\t[--break] [--c <framecount>] [--suppress_popups]\n"
+ "\t[--incremental_present] [--display_timing]\n"
+ "\t[--present_mode <present mode enum>]\n"
+ "\t<present_mode_enum>\n"
+ "\t\tVK_PRESENT_MODE_IMMEDIATE_KHR = %d\n"
+ "\t\tVK_PRESENT_MODE_MAILBOX_KHR = %d\n"
+ "\t\tVK_PRESENT_MODE_FIFO_KHR = %d\n"
+ "\t\tVK_PRESENT_MODE_FIFO_RELAXED_KHR = %d\n";
+ int length = snprintf(NULL, 0, message, APP_SHORT_NAME, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR,
+ VK_PRESENT_MODE_FIFO_KHR, VK_PRESENT_MODE_FIFO_RELAXED_KHR);
+ char *usage = (char *)malloc(length + 1);
+ if (!usage) {
+ exit(1);
+ }
+ snprintf(usage, length + 1, message, APP_SHORT_NAME, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_MAILBOX_KHR,
+ VK_PRESENT_MODE_FIFO_KHR, VK_PRESENT_MODE_FIFO_RELAXED_KHR);
+#if defined(_WIN32)
+ if (!demo->suppress_popups) MessageBox(NULL, usage, "Usage Error", MB_OK);
+#else
+ fprintf(stderr, "%s", usage);
fflush(stderr);
+#endif
+ free(usage);
exit(1);
#endif
}
}
demo.connection = hInstance;
- strncpy(demo.name, "cube", APP_NAME_STR_LEN);
+ strncpy(demo.name, "Vulkan Cube", APP_NAME_STR_LEN);
demo_create_window(&demo);
demo_init_vk_swapchain(&demo);
// main message loop
while (!done) {
+ if (demo.pause) {
+ const BOOL succ = WaitMessage();
+
+ if (!succ) {
+ struct demo *tmp = &demo;
+ struct demo *demo = tmp;
+ ERR_EXIT("WaitMessage() failed on paused demo", "event loop error");
+ }
+ }
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
if (msg.message == WM_QUIT) // check for a quit message
{
return (int)msg.wParam;
}
-#elif defined(VK_USE_PLATFORM_IOS_MVK) || defined(VK_USE_PLATFORM_MACOS_MVK)
-static void demo_main(struct demo *demo, void *view, int argc, const char *argv[]) {
-
+#elif defined(VK_USE_PLATFORM_METAL_EXT)
+static void demo_main(struct demo *demo, void *caMetalLayer, int argc, const char *argv[]) {
demo_init(demo, argc, (char **)argv);
- demo->window = view;
+ demo->caMetalLayer = caMetalLayer;
demo_init_vk_swapchain(demo);
demo_prepare(demo);
demo->spin_angle = 0.4f;
demo_create_xlib_window(&demo);
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
demo_create_window(&demo);
-#elif defined(VK_USE_PLATFORM_MIR_KHR)
#endif
demo_init_vk_swapchain(&demo);
demo_run_xlib(&demo);
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
demo_run(&demo);
-#elif defined(VK_USE_PLATFORM_MIR_KHR)
#elif defined(VK_USE_PLATFORM_DISPLAY_KHR)
demo_run_display(&demo);
#endif