diff --git a/Editor/Editor.vcxproj b/Editor/Editor.vcxproj
index 33c056d79..2da0966b6 100644
--- a/Editor/Editor.vcxproj
+++ b/Editor/Editor.vcxproj
@@ -103,7 +103,7 @@
Windows
true
- ../$(Platform)/$(Configuration)
+ ../$(Platform)/$(Configuration);$(VULKAN_SDK)/Lib32
@@ -117,7 +117,7 @@
Windows
true
- ../$(Platform)/$(Configuration)
+ ../$(Platform)/$(Configuration);$(VULKAN_SDK)/Lib
@@ -141,7 +141,7 @@
true
true
true
- ../$(Platform)/$(Configuration)
+ ../$(Platform)/$(Configuration);$(VULKAN_SDK)/Lib32
@@ -161,7 +161,7 @@
true
true
true
- ../$(Platform)/$(Configuration)
+ ../$(Platform)/$(Configuration);$(VULKAN_SDK)/Lib
diff --git a/Template_Windows/Template_Windows.vcxproj b/Template_Windows/Template_Windows.vcxproj
index 4c096050f..67de2a88e 100644
--- a/Template_Windows/Template_Windows.vcxproj
+++ b/Template_Windows/Template_Windows.vcxproj
@@ -105,7 +105,7 @@
true
true
true
- ../$(Platform)/$(Configuration)
+ ../$(Platform)/$(Configuration);$(VULKAN_SDK)/Lib
@@ -120,7 +120,7 @@
Windows
true
- ../$(Platform)/$(Configuration)
+ ../$(Platform)/$(Configuration);$(VULKAN_SDK)/Lib32
@@ -135,7 +135,7 @@
Windows
true
- ../$(Platform)/$(Configuration)
+ ../$(Platform)/$(Configuration);$(VULKAN_SDK)/Lib
@@ -155,7 +155,7 @@
true
true
true
- ../$(Platform)/$(Configuration)
+ ../$(Platform)/$(Configuration);$(VULKAN_SDK)/Lib32
diff --git a/Tests/Tests.vcxproj b/Tests/Tests.vcxproj
index 9dd27ff72..4bc6a8d6a 100644
--- a/Tests/Tests.vcxproj
+++ b/Tests/Tests.vcxproj
@@ -110,7 +110,7 @@
true
true
true
- ../$(Platform)/$(Configuration)
+ ../$(Platform)/$(Configuration);$(VULKAN_SDK)/Lib
@@ -126,7 +126,7 @@
Windows
true
- ../$(Platform)/$(Configuration)
+ ../$(Platform)/$(Configuration);$(VULKAN_SDK)/Lib32
@@ -142,7 +142,7 @@
Windows
true
- ../$(Platform)/$(Configuration)
+ ../$(Platform)/$(Configuration);$(VULKAN_SDK)/Lib
@@ -162,7 +162,7 @@
true
true
true
- ../$(Platform)/$(Configuration)
+ ../$(Platform)/$(Configuration);$(VULKAN_SDK)/Lib32
diff --git a/WickedEngine.sln b/WickedEngine.sln
index c93b82ddc..9754c6b1c 100644
--- a/WickedEngine.sln
+++ b/WickedEngine.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
-VisualStudioVersion = 15.0.26730.16
+VisualStudioVersion = 15.0.27130.2036
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WickedEngine_SHARED", "WickedEngine\WickedEngine_SHARED.vcxitems", "{45D41ACC-2C3C-43D2-BC10-02AA73FFC7C7}"
EndProject
@@ -42,8 +42,8 @@ Global
{06163DCB-B183-4ED9-9C62-13EF1658E049}.Release|Win32.Build.0 = Release|Win32
{06163DCB-B183-4ED9-9C62-13EF1658E049}.Release|x64.ActiveCfg = Release|x64
{06163DCB-B183-4ED9-9C62-13EF1658E049}.Release|x64.Build.0 = Release|x64
- {60DA258F-E95F-4CF4-A46B-17D80644464B}.Debug|ARM.ActiveCfg = Debug|x64
- {60DA258F-E95F-4CF4-A46B-17D80644464B}.Debug|ARM.Build.0 = Debug|x64
+ {60DA258F-E95F-4CF4-A46B-17D80644464B}.Debug|ARM.ActiveCfg = Debug|ARM
+ {60DA258F-E95F-4CF4-A46B-17D80644464B}.Debug|ARM.Build.0 = Debug|ARM
{60DA258F-E95F-4CF4-A46B-17D80644464B}.Debug|Win32.ActiveCfg = Debug|Win32
{60DA258F-E95F-4CF4-A46B-17D80644464B}.Debug|Win32.Build.0 = Debug|Win32
{60DA258F-E95F-4CF4-A46B-17D80644464B}.Debug|x64.ActiveCfg = Debug|x64
diff --git a/WickedEngine/wiGraphicsDevice_Vulkan.cpp b/WickedEngine/wiGraphicsDevice_Vulkan.cpp
index 237364688..fd0189a2d 100644
--- a/WickedEngine/wiGraphicsDevice_Vulkan.cpp
+++ b/WickedEngine/wiGraphicsDevice_Vulkan.cpp
@@ -1,3 +1,4 @@
+#define _CRT_SECURE_NO_WARNINGS
#include "wiGraphicsDevice_Vulkan.h"
#include "wiHelper.h"
#include "ResourceMapping.h"
@@ -11,11 +12,622 @@ using namespace std;
#ifdef WICKEDENGINE_BUILD_VULKAN
#pragma comment(lib,"vulkan-1.lib")
+bool in_callback = false;
+#define ERR_EXIT(err_msg, err_class) \
+ do { \
+ if (!this->suppress_popups) MessageBoxA(NULL, err_msg, err_class, MB_OK); \
+ exit(1); \
+ } while (0)
+void DbgMsg(char *fmt, ...) {
+ va_list va;
+ va_start(va, fmt);
+ printf(fmt, va);
+ fflush(stdout);
+ va_end(va);
+}
+VKAPI_ATTR VkBool32 VKAPI_CALL BreakCallback(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject,
+ size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg,
+ void *pUserData) {
+#ifndef WIN32
+ raise(SIGTRAP);
+#else
+ DebugBreak();
+#endif
+
+ return false;
+}
+
+static int validation_error = 0;
+VKAPI_ATTR VkBool32 VKAPI_CALL dbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location,
+ int32_t msgCode, const char *pLayerPrefix, const char *pMsg, void *pUserData) {
+ // clang-format off
+ char *message = (char *)malloc(strlen(pMsg) + 100);
+
+ assert(message);
+
+ if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
+ sprintf(message, "INFORMATION: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
+ validation_error = 1;
+ }
+ else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
+ sprintf(message, "WARNING: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
+ validation_error = 1;
+ }
+ else if (msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
+ sprintf(message, "PERFORMANCE WARNING: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
+ validation_error = 1;
+ }
+ else if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
+ sprintf(message, "ERROR: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
+ validation_error = 1;
+ }
+ else if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
+ sprintf(message, "DEBUG: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
+ validation_error = 1;
+ }
+ else {
+ sprintf(message, "INFORMATION: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
+ validation_error = 1;
+ }
+
+#ifdef _WIN32
+
+ in_callback = true;
+ struct demo *demo = (struct demo*) pUserData;
+ MessageBoxA(NULL, message, "Alert", MB_OK);
+ in_callback = false;
+
+#elif defined(ANDROID)
+
+ if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
+ __android_log_print(ANDROID_LOG_INFO, APP_SHORT_NAME, "%s", message);
+ }
+ else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
+ __android_log_print(ANDROID_LOG_WARN, APP_SHORT_NAME, "%s", message);
+ }
+ else if (msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
+ __android_log_print(ANDROID_LOG_WARN, APP_SHORT_NAME, "%s", message);
+ }
+ else if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
+ __android_log_print(ANDROID_LOG_ERROR, APP_SHORT_NAME, "%s", message);
+ }
+ else if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
+ __android_log_print(ANDROID_LOG_DEBUG, APP_SHORT_NAME, "%s", message);
+ }
+ else {
+ __android_log_print(ANDROID_LOG_INFO, APP_SHORT_NAME, "%s", message);
+ }
+
+#else
+
+ printf("%s\n", message);
+ fflush(stdout);
+
+#endif
+
+ free(message);
+
+ // clang-format on
+
+ /*
+ * false indicates that layer should not bail-out of an
+ * API call that had validation failures. This may mean that the
+ * app dies inside the driver due to invalid parameter(s).
+ * That's what would happen without validation layers, so we'll
+ * keep that behavior here.
+ */
+ return false;
+}
+
+
+static VkBool32 demo_check_layers(uint32_t check_count, char **check_names,
+ uint32_t layer_count,
+ VkLayerProperties *layers) {
+ for (uint32_t i = 0; i < check_count; i++) {
+ VkBool32 found = 0;
+ for (uint32_t j = 0; j < layer_count; j++) {
+ if (!strcmp(check_names[i], layers[j].layerName)) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ fprintf(stderr, "Cannot find layer: %s\n", check_names[i]);
+ return 0;
+ }
+ }
+ return 1;
+}
+
namespace wiGraphicsTypes
{
// Engine functions
GraphicsDevice_Vulkan::GraphicsDevice_Vulkan(wiWindowRegistration::window_type window, bool fullscreen) : GraphicsDevice()
{
+ FULLSCREEN = fullscreen;
+
+ RECT rect = RECT();
+ GetClientRect(window, &rect);
+ SCREENWIDTH = rect.right - rect.left;
+ SCREENHEIGHT = rect.bottom - rect.top;
+
+ 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;
+
+ this->enabled_extension_count = 0;
+ this->enabled_layer_count = 0;
+ this->validate = true;
+
+ 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 */
+ VkBool32 validation_found = 0;
+ if (validate) {
+
+ err = vkEnumerateInstanceLayerProperties(&instance_layer_count, NULL);
+ assert(!err);
+
+ instance_validation_layers = instance_validation_layers_alt1;
+ if (instance_layer_count > 0) {
+ VkLayerProperties *instance_layers =
+ (VkLayerProperties*)malloc(sizeof(VkLayerProperties) * instance_layer_count);
+ err = vkEnumerateInstanceLayerProperties(&instance_layer_count,
+ instance_layers);
+ assert(!err);
+
+
+ validation_found = demo_check_layers(
+ ARRAYSIZE(instance_validation_layers_alt1),
+ instance_validation_layers, instance_layer_count,
+ instance_layers);
+ if (validation_found) {
+ this->enabled_layer_count = ARRAYSIZE(instance_validation_layers_alt1);
+ this->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;
+ this->enabled_layer_count = ARRAYSIZE(instance_validation_layers_alt2);
+ validation_found = demo_check_layers(
+ ARRAYSIZE(instance_validation_layers_alt2),
+ instance_validation_layers, instance_layer_count,
+ instance_layers);
+ validation_layer_count =
+ ARRAYSIZE(instance_validation_layers_alt2);
+ for (uint32_t i = 0; i < validation_layer_count; i++) {
+ this->enabled_layers[i] = instance_validation_layers[i];
+ }
+ }
+ free(instance_layers);
+ }
+
+ if (!validation_found) {
+ ERR_EXIT("vkEnumerateInstanceLayerProperties failed to find "
+ "required validation layer.\n\n"
+ "Please look at the Getting Started guide for additional "
+ "information.\n",
+ "vkCreateInstance Failure");
+ }
+ }
+
+ /* Look for instance extensions */
+ VkBool32 surfaceExtFound = 0;
+ VkBool32 platformSurfaceExtFound = 0;
+ memset(this->extension_names, 0, sizeof(this->extension_names));
+
+ err = vkEnumerateInstanceExtensionProperties(
+ NULL, &instance_extension_count, NULL);
+ assert(!err);
+
+ if (instance_extension_count > 0) {
+ VkExtensionProperties *instance_extensions =
+ (VkExtensionProperties*)malloc(sizeof(VkExtensionProperties) * instance_extension_count);
+ err = vkEnumerateInstanceExtensionProperties(
+ NULL, &instance_extension_count, instance_extensions);
+ assert(!err);
+ for (uint32_t i = 0; i < instance_extension_count; i++) {
+ if (!strcmp(VK_KHR_SURFACE_EXTENSION_NAME,
+ instance_extensions[i].extensionName)) {
+ surfaceExtFound = 1;
+ this->extension_names[this->enabled_extension_count++] =
+ VK_KHR_SURFACE_EXTENSION_NAME;
+ }
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+ if (!strcmp(VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
+ instance_extensions[i].extensionName)) {
+ platformSurfaceExtFound = 1;
+ this->extension_names[this->enabled_extension_count++] =
+ VK_KHR_WIN32_SURFACE_EXTENSION_NAME;
+ }
+#elif defined(VK_USE_PLATFORM_XLIB_KHR)
+ if (!strcmp(VK_KHR_XLIB_SURFACE_EXTENSION_NAME,
+ instance_extensions[i].extensionName)) {
+ platformSurfaceExtFound = 1;
+ this->extension_names[this->enabled_extension_count++] =
+ VK_KHR_XLIB_SURFACE_EXTENSION_NAME;
+ }
+#elif defined(VK_USE_PLATFORM_XCB_KHR)
+ if (!strcmp(VK_KHR_XCB_SURFACE_EXTENSION_NAME,
+ instance_extensions[i].extensionName)) {
+ platformSurfaceExtFound = 1;
+ this->extension_names[this->enabled_extension_count++] =
+ VK_KHR_XCB_SURFACE_EXTENSION_NAME;
+ }
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+ if (!strcmp(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME,
+ instance_extensions[i].extensionName)) {
+ platformSurfaceExtFound = 1;
+ this->extension_names[this->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;
+ this->extension_names[this->enabled_extension_count++] =
+ VK_KHR_DISPLAY_EXTENSION_NAME;
+ }
+#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
+ if (!strcmp(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
+ instance_extensions[i].extensionName)) {
+ platformSurfaceExtFound = 1;
+ this->extension_names[this->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)) {
+ platformSurfaceExtFound = 1;
+ this->extension_names[this->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;
+ this->extension_names[this->enabled_extension_count++] = VK_MVK_MACOS_SURFACE_EXTENSION_NAME;
+ }
+#endif
+ if (!strcmp(VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
+ instance_extensions[i].extensionName)) {
+ if (this->validate) {
+ this->extension_names[this->enabled_extension_count++] =
+ VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
+ }
+ }
+ assert(this->enabled_extension_count < 64);
+ }
+
+ free(instance_extensions);
+ }
+
+ if (!surfaceExtFound) {
+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find "
+ "the " VK_KHR_SURFACE_EXTENSION_NAME
+ " extension.\n\nDo you have a compatible "
+ "Vulkan installable client driver (ICD) installed?\nPlease "
+ "look at the Getting Started guide for additional "
+ "information.\n",
+ "vkCreateInstance Failure");
+ }
+ if (!platformSurfaceExtFound) {
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find "
+ "the " VK_KHR_WIN32_SURFACE_EXTENSION_NAME
+ " extension.\n\nDo you have a compatible "
+ "Vulkan installable client driver (ICD) installed?\nPlease "
+ "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\nDo you have a compatible "
+ "Vulkan installable client driver (ICD) installed?\nPlease "
+ "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" extension.\n\nDo you have a compatible "
+ "Vulkan installable client driver (ICD) installed?\nPlease "
+ "look at the Getting Started guide for additional "
+ "information.\n",
+ "vkCreateInstance Failure");
+#elif defined(VK_USE_PLATFORM_XCB_KHR)
+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find "
+ "the " VK_KHR_XCB_SURFACE_EXTENSION_NAME
+ " extension.\n\nDo you have a compatible "
+ "Vulkan installable client driver (ICD) installed?\nPlease "
+ "look at the Getting Started guide for additional "
+ "information.\n",
+ "vkCreateInstance Failure");
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find "
+ "the " VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
+ " extension.\n\nDo you have a compatible "
+ "Vulkan installable client driver (ICD) installed?\nPlease "
+ "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\nDo you have a compatible "
+ "Vulkan installable client driver (ICD) installed?\nPlease "
+ "look at the Getting Started guide for additional "
+ "information.\n",
+ "vkCreateInstance Failure");
+#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find "
+ "the " VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
+ " extension.\n\nDo you have a compatible "
+ "Vulkan installable client driver (ICD) installed?\nPlease "
+ "look at the Getting Started guide for additional "
+ "information.\n",
+ "vkCreateInstance Failure");
+#elif defined(VK_USE_PLATFORM_XLIB_KHR)
+ ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find "
+ "the " VK_KHR_XLIB_SURFACE_EXTENSION_NAME
+ " extension.\n\nDo you have a compatible "
+ "Vulkan installable client driver (ICD) installed?\nPlease "
+ "look at the Getting Started guide for additional "
+ "information.\n",
+ "vkCreateInstance Failure");
+#endif
+ }
+ VkApplicationInfo app;
+ app.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
+ app.pNext = NULL;
+ app.pApplicationName = "WickedEngine";
+ app.applicationVersion = 0;
+ app.pEngineName = "Wickedengine";
+ app.engineVersion = 0;
+ app.apiVersion = VK_API_VERSION_1_0;
+
+ VkInstanceCreateInfo inst_info;
+ inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
+ inst_info.pNext = NULL;
+ inst_info.pApplicationInfo = &app;
+ inst_info.enabledLayerCount = this->enabled_layer_count;
+ inst_info.ppEnabledLayerNames = (const char *const *)instance_validation_layers;
+ inst_info.enabledExtensionCount = this->enabled_extension_count;
+ inst_info.ppEnabledExtensionNames = (const char *const *)this->extension_names;
+
+ /*
+ * This is info for a temp callback to use during CreateInstance.
+ * After the instance is created, we use the instance-based
+ * function to register the final callback.
+ */
+ VkDebugReportCallbackCreateInfoEXT dbgCreateInfoTemp;
+ VkValidationFlagsEXT val_flags;
+ if (this->validate) {
+ dbgCreateInfoTemp.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
+ dbgCreateInfoTemp.pNext = NULL;
+ dbgCreateInfoTemp.pfnCallback = this->use_break ? BreakCallback : dbgFunc;
+ dbgCreateInfoTemp.pUserData = this;
+ dbgCreateInfoTemp.flags =
+ VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
+ if (this->validate_checks_disabled) {
+ val_flags.sType = VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT;
+ val_flags.pNext = NULL;
+ val_flags.disabledValidationCheckCount = 1;
+ VkValidationCheckEXT disabled_check = VK_VALIDATION_CHECK_ALL_EXT;
+ val_flags.pDisabledValidationChecks = &disabled_check;
+ dbgCreateInfoTemp.pNext = (void*)&val_flags;
+ }
+ inst_info.pNext = &dbgCreateInfoTemp;
+ }
+
+ uint32_t gpu_count;
+
+ err = vkCreateInstance(&inst_info, NULL, &this->inst);
+ if (err == VK_ERROR_INCOMPATIBLE_DRIVER) {
+ ERR_EXIT("Cannot find a compatible Vulkan installable client driver "
+ "(ICD).\n\nPlease look at the Getting Started guide for "
+ "additional information.\n",
+ "vkCreateInstance Failure");
+ }
+ else if (err == VK_ERROR_EXTENSION_NOT_PRESENT) {
+ ERR_EXIT("Cannot find a specified extension library"
+ ".\nMake sure your layers path is set appropriately.\n",
+ "vkCreateInstance Failure");
+ }
+ else if (err) {
+ ERR_EXIT("vkCreateInstance failed.\n\nDo you have a compatible Vulkan "
+ "installable client driver (ICD) installed?\nPlease look at "
+ "the Getting Started guide for additional information.\n",
+ "vkCreateInstance Failure");
+ }
+
+ /* Make initial call to query gpu_count, then second call for gpu info*/
+ err = vkEnumeratePhysicalDevices(this->inst, &gpu_count, NULL);
+ assert(!err && gpu_count > 0);
+
+ if (gpu_count > 0) {
+ VkPhysicalDevice *physical_devices = (VkPhysicalDevice*)malloc(sizeof(VkPhysicalDevice) * gpu_count);
+ err = vkEnumeratePhysicalDevices(this->inst, &gpu_count, physical_devices);
+ assert(!err);
+ /* For cube demo we just grab the first physical device */
+ this->gpu = physical_devices[0];
+ free(physical_devices);
+ }
+ else {
+ ERR_EXIT("vkEnumeratePhysicalDevices reported zero accessible devices.\n\n"
+ "Do you have a compatible Vulkan installable client driver (ICD) "
+ "installed?\nPlease look at the Getting Started guide for "
+ "additional information.\n",
+ "vkEnumeratePhysicalDevices Failure");
+ }
+
+ /* Look for device extensions */
+ uint32_t device_extension_count = 0;
+ VkBool32 swapchainExtFound = 0;
+ this->enabled_extension_count = 0;
+ memset(this->extension_names, 0, sizeof(this->extension_names));
+
+ err = vkEnumerateDeviceExtensionProperties(this->gpu, NULL,
+ &device_extension_count, NULL);
+ assert(!err);
+
+ if (device_extension_count > 0) {
+ VkExtensionProperties *device_extensions =
+ (VkExtensionProperties*)malloc(sizeof(VkExtensionProperties) * device_extension_count);
+ err = vkEnumerateDeviceExtensionProperties(
+ this->gpu, NULL, &device_extension_count, device_extensions);
+ assert(!err);
+
+ for (uint32_t i = 0; i < device_extension_count; i++) {
+ if (!strcmp(VK_KHR_SWAPCHAIN_EXTENSION_NAME,
+ device_extensions[i].extensionName)) {
+ swapchainExtFound = 1;
+ this->extension_names[this->enabled_extension_count++] =
+ VK_KHR_SWAPCHAIN_EXTENSION_NAME;
+ }
+ assert(this->enabled_extension_count < 64);
+ }
+
+ if (this->VK_KHR_incremental_present_enabled) {
+ // Even though the user "enabled" the extension via the command
+ // line, we must make sure that it's enumerated for use with the
+ // device. Therefore, disable it here, and re-enable it again if
+ // enumerated.
+ this->VK_KHR_incremental_present_enabled = false;
+ for (uint32_t i = 0; i < device_extension_count; i++) {
+ if (!strcmp(VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME,
+ device_extensions[i].extensionName)) {
+ this->extension_names[this->enabled_extension_count++] =
+ VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME;
+ this->VK_KHR_incremental_present_enabled = true;
+ DbgMsg("VK_KHR_incremental_present extension enabled\n");
+ }
+ assert(this->enabled_extension_count < 64);
+ }
+ if (!this->VK_KHR_incremental_present_enabled) {
+ DbgMsg("VK_KHR_incremental_present extension NOT AVAILABLE\n");
+ }
+ }
+
+ if (this->VK_GOOGLE_display_timing_enabled) {
+ // Even though the user "enabled" the extension via the command
+ // line, we must make sure that it's enumerated for use with the
+ // device. Therefore, disable it here, and re-enable it again if
+ // enumerated.
+ this->VK_GOOGLE_display_timing_enabled = false;
+ for (uint32_t i = 0; i < device_extension_count; i++) {
+ if (!strcmp(VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME,
+ device_extensions[i].extensionName)) {
+ this->extension_names[this->enabled_extension_count++] =
+ VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME;
+ this->VK_GOOGLE_display_timing_enabled = true;
+ DbgMsg("VK_GOOGLE_display_timing extension enabled\n");
+ }
+ assert(this->enabled_extension_count < 64);
+ }
+ if (!this->VK_GOOGLE_display_timing_enabled) {
+ DbgMsg("VK_GOOGLE_display_timing extension NOT AVAILABLE\n");
+ }
+ }
+
+ free(device_extensions);
+ }
+
+ if (!swapchainExtFound) {
+ ERR_EXIT("vkEnumerateDeviceExtensionProperties failed to find "
+ "the " VK_KHR_SWAPCHAIN_EXTENSION_NAME
+ " extension.\n\nDo you have a compatible "
+ "Vulkan installable client driver (ICD) installed?\nPlease "
+ "look at the Getting Started guide for additional "
+ "information.\n",
+ "vkCreateInstance Failure");
+ }
+
+ if (this->validate) {
+ this->CreateDebugReportCallback =
+ (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(
+ this->inst, "vkCreateDebugReportCallbackEXT");
+ this->DestroyDebugReportCallback =
+ (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(
+ this->inst, "vkDestroyDebugReportCallbackEXT");
+ if (!this->CreateDebugReportCallback) {
+ ERR_EXIT(
+ "GetProcAddr: Unable to find vkCreateDebugReportCallbackEXT\n",
+ "vkGetProcAddr Failure");
+ }
+ if (!this->DestroyDebugReportCallback) {
+ ERR_EXIT(
+ "GetProcAddr: Unable to find vkDestroyDebugReportCallbackEXT\n",
+ "vkGetProcAddr Failure");
+ }
+ this->DebugReportMessage =
+ (PFN_vkDebugReportMessageEXT)vkGetInstanceProcAddr(
+ this->inst, "vkDebugReportMessageEXT");
+ if (!this->DebugReportMessage) {
+ ERR_EXIT("GetProcAddr: Unable to find vkDebugReportMessageEXT\n",
+ "vkGetProcAddr Failure");
+ }
+
+ VkDebugReportCallbackCreateInfoEXT dbgCreateInfo;
+ PFN_vkDebugReportCallbackEXT callback;
+ callback = this->use_break ? BreakCallback : dbgFunc;
+ dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
+ dbgCreateInfo.pNext = NULL;
+ dbgCreateInfo.pfnCallback = callback;
+ dbgCreateInfo.pUserData = this;
+ dbgCreateInfo.flags =
+ VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
+ err = this->CreateDebugReportCallback(this->inst, &dbgCreateInfo, NULL,
+ &this->msg_callback);
+ switch (err) {
+ case VK_SUCCESS:
+ break;
+ case VK_ERROR_OUT_OF_HOST_MEMORY:
+ ERR_EXIT("CreateDebugReportCallback: out of host memory\n",
+ "CreateDebugReportCallback Failure");
+ break;
+ default:
+ ERR_EXIT("CreateDebugReportCallback: unknown failure\n",
+ "CreateDebugReportCallback Failure");
+ break;
+ }
+ }
+ vkGetPhysicalDeviceProperties(this->gpu, &this->gpu_props);
+
+ /* Call with NULL data to get count */
+ vkGetPhysicalDeviceQueueFamilyProperties(this->gpu,
+ &this->queue_family_count, NULL);
+ assert(this->queue_family_count >= 1);
+
+ this->queue_props = (VkQueueFamilyProperties *)malloc(
+ this->queue_family_count * sizeof(VkQueueFamilyProperties));
+ vkGetPhysicalDeviceQueueFamilyProperties(
+ this->gpu, &this->queue_family_count, this->queue_props);
+
+ // Query fine-grained feature support for this device.
+ // If app has specific feature requirements it should check supported
+ // features based on this query
+ VkPhysicalDeviceFeatures physDevFeatures;
+ vkGetPhysicalDeviceFeatures(this->gpu, &physDevFeatures);
+
+ //GET_INSTANCE_PROC_ADDR(this->inst, GetPhysicalDeviceSurfaceSupportKHR);
+ //GET_INSTANCE_PROC_ADDR(this->inst, GetPhysicalDeviceSurfaceCapabilitiesKHR);
+ //GET_INSTANCE_PROC_ADDR(this->inst, GetPhysicalDeviceSurfaceFormatsKHR);
+ //GET_INSTANCE_PROC_ADDR(this->inst, GetPhysicalDeviceSurfacePresentModesKHR);
+ //GET_INSTANCE_PROC_ADDR(this->inst, GetSwapchainImagesKHR);
+
+
+
+
}
GraphicsDevice_Vulkan::~GraphicsDevice_Vulkan()
{
@@ -41,6 +653,10 @@ namespace wiGraphicsTypes
{
return E_FAIL;
}
+ HRESULT GraphicsDevice_Vulkan::CreateTexture1D(const Texture1DDesc* pDesc, const SubresourceData *pInitialData, Texture1D **ppTexture1D)
+ {
+ return E_FAIL;
+ }
HRESULT GraphicsDevice_Vulkan::CreateTexture2D(const Texture2DDesc* pDesc, const SubresourceData *pInitialData, Texture2D **ppTexture2D)
{
return E_FAIL;
@@ -125,6 +741,18 @@ namespace wiGraphicsTypes
void GraphicsDevice_Vulkan::BindViewports(UINT NumViewports, const ViewPort *pViewports, GRAPHICSTHREAD threadID)
{
+ assert(NumViewports <= 6);
+ VkViewport viewports[6];
+ for (UINT i = 0; i < NumViewports; ++i)
+ {
+ viewports[i].x = pViewports[i].TopLeftX;
+ viewports[i].y = pViewports[i].TopLeftY;
+ viewports[i].width = pViewports[i].Width;
+ viewports[i].height = pViewports[i].Height;
+ viewports[i].minDepth = pViewports[i].MinDepth;
+ viewports[i].maxDepth = pViewports[i].MaxDepth;
+ }
+ vkCmdSetViewport(commandBuffers[threadID], 0, NumViewports, viewports);
}
void GraphicsDevice_Vulkan::BindRenderTargetsUAVs(UINT NumViews, Texture* const *ppRenderTargets, Texture2D* depthStencilTexture, GPUResource* const *ppUAVs, int slotUAV, int countUAV,
GRAPHICSTHREAD threadID, int arrayIndex)
@@ -243,6 +871,17 @@ namespace wiGraphicsTypes
}
void GraphicsDevice_Vulkan::SetScissorRects(UINT numRects, const Rect* rects, GRAPHICSTHREAD threadID)
{
+ assert(rects != nullptr);
+ assert(numRects <= 8);
+ VkRect2D scissors[8];
+ for (UINT i = 0; i < numRects; ++i)
+ {
+ scissors[i].extent.width = abs(rects[i].right - rects[i].left);
+ scissors[i].extent.height = abs(rects[i].bottom - rects[i].top);
+ scissors[i].offset.x = rects[i].left;
+ scissors[i].offset.y = rects[i].bottom;
+ }
+ vkCmdSetScissor(commandBuffers[threadID], 0, numRects, scissors);
}
void GraphicsDevice_Vulkan::QueryBegin(GPUQuery *query, GRAPHICSTHREAD threadID)
@@ -289,4 +928,5 @@ namespace wiGraphicsTypes
}
+
#endif // WICKEDENGINE_BUILD_VULKAN
diff --git a/WickedEngine/wiGraphicsDevice_Vulkan.h b/WickedEngine/wiGraphicsDevice_Vulkan.h
index 7c8ebb700..9c41c8b01 100644
--- a/WickedEngine/wiGraphicsDevice_Vulkan.h
+++ b/WickedEngine/wiGraphicsDevice_Vulkan.h
@@ -46,6 +46,8 @@ namespace wiGraphicsTypes
VkQueueFamilyProperties *queue_props;
VkPhysicalDeviceMemoryProperties memory_properties;
+ VkCommandBuffer commandBuffers[GRAPHICSTHREAD_COUNT];
+
uint32_t enabled_extension_count;
uint32_t enabled_layer_count;
char *extension_names[64];
@@ -84,6 +86,26 @@ namespace wiGraphicsTypes
VkFence fences[BACKBUFFER_COUNT];
int frame_index;
+
+
+
+ VkDescriptorPool desc_pool;
+
+ bool quit;
+ int32_t curFrame;
+ int32_t frameCount;
+ bool validate;
+ bool validate_checks_disabled;
+ bool use_break;
+ bool suppress_popups;
+ PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallback;
+ PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallback;
+ VkDebugReportCallbackEXT msg_callback;
+ PFN_vkDebugReportMessageEXT DebugReportMessage;
+
+ uint32_t current_buffer;
+ uint32_t queue_family_count;
+
public:
GraphicsDevice_Vulkan(wiWindowRegistration::window_type window, bool fullscreen = false);
diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp
index cc6f29ec6..fe6ff5162 100644
--- a/WickedEngine/wiRenderer.cpp
+++ b/WickedEngine/wiRenderer.cpp
@@ -21,6 +21,7 @@
#include "wiFont.h"
#include "wiGraphicsDevice_DX11.h"
#include "wiGraphicsDevice_DX12.h"
+#include "wiGraphicsDevice_Vulkan.h"
#include "wiTranslator.h"
#include "wiRectPacker.h"
#include "wiBackLog.h"
@@ -124,8 +125,12 @@ wiRenderer::wiRenderer()
void wiRenderer::InitDevice(wiWindowRegistration::window_type window, bool fullscreen)
{
SAFE_DELETE(graphicsDevice);
+#ifdef WICKEDENGINE_BUILD_VULKAN
+ graphicsDevice = new GraphicsDevice_Vulkan(window, fullscreen);
+#else
graphicsDevice = new GraphicsDevice_DX11(window, fullscreen);
//graphicsDevice = new GraphicsDevice_DX12(window, fullscreen);
+#endif
}
void wiRenderer::Present(function drawToScreen1,function drawToScreen2,function drawToScreen3)