From 1ca6af364edbfc6bcc45bf603a11a0ddeb16c50e Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Thu, 23 Jul 2020 17:03:40 -0700 Subject: [PATCH] Implemented KrCreateWindowSurface and KrDeleteWindowSurface --- kraken/KRContext.cpp | 61 +++++++++++++++++++++++++---- kraken/KRContext.h | 2 + kraken/kraken.cpp | 8 ++-- kraken/public/kraken.h | 21 ++++++---- tests/smoke/hello_cube/main_win.cpp | 31 +++++++++++++-- 5 files changed, 101 insertions(+), 22 deletions(-) diff --git a/kraken/KRContext.cpp b/kraken/KRContext.cpp index f491353..9679e5e 100755 --- a/kraken/KRContext.cpp +++ b/kraken/KRContext.cpp @@ -164,7 +164,7 @@ KRContext::~KRContext() { delete m_pBundleManager; m_pBundleManager = NULL; } - + destroySurfaces(); destroyDeviceContexts(); if (m_resourceMap) { delete m_resourceMap; @@ -676,6 +676,14 @@ KRContext::createDeviceContexts() app_info.engineVersion = 1; app_info.apiVersion = VK_API_VERSION_1_0; + // VK_KHR_surface and VK_KHR_win32_surface + + char* extensions[] = { + "VK_KHR_surface", +#ifdef WIN32 + "VK_KHR_win32_surface", +#endif + }; // initialize the VkInstanceCreateInfo structure VkInstanceCreateInfo inst_info = {}; @@ -683,8 +691,12 @@ KRContext::createDeviceContexts() inst_info.pNext = NULL; inst_info.flags = 0; inst_info.pApplicationInfo = &app_info; - inst_info.enabledExtensionCount = 0; - inst_info.ppEnabledExtensionNames = NULL; +#ifdef WIN32 + inst_info.enabledExtensionCount = 2; +#else + inst_info.enabledExtensionCount = 1; +#endif + inst_info.ppEnabledExtensionNames = extensions; inst_info.enabledLayerCount = 0; inst_info.ppEnabledLayerNames = NULL; @@ -705,6 +717,19 @@ KRContext::destroyDeviceContexts() } } +void +KRContext::destroySurfaces() +{ + if (m_vulkanInstance == VK_NULL_HANDLE) { + return; + } + for (auto itr = m_surfaces.begin(); itr != m_surfaces.end(); itr++) { + SurfaceInfo* surfaceInfo = &(*itr).second; + vkDestroySurfaceKHR(m_vulkanInstance, surfaceInfo->surface, nullptr); + } + m_surfaces.clear(); +} + void KRContext::activateStreamerContext() { @@ -795,16 +820,29 @@ KrResult KRContext::createWindowSurface(const KrCreateWindowSurfaceInfo* createW if (createWindowSurfaceInfo->surfaceHandle < 0) { return KR_ERROR_OUT_OF_BOUNDS; } + if (m_vulkanInstance == VK_NULL_HANDLE) { + return KR_ERROR_VULKAN_REQUIRED; + } if (m_surfaces.count(createWindowSurfaceInfo->surfaceHandle)) { return KR_ERROR_DUPLICATE_HANDLE; } SurfaceInfo info{}; info.surfaceHandle = createWindowSurfaceInfo->surfaceHandle; + #ifdef WIN32 info.hWnd = static_cast(createWindowSurfaceInfo->hWnd); + + VkWin32SurfaceCreateInfoKHR createInfo{}; + createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; + createInfo.hinstance = GetModuleHandle(nullptr); + createInfo.hwnd = info.hWnd; + + if(vkCreateWin32SurfaceKHR(m_vulkanInstance, &createInfo, nullptr, &info.surface) != VK_SUCCESS) { + return KR_ERROR_VULKAN; + } m_surfaces.insert(std::pair(createWindowSurfaceInfo->surfaceHandle, info)); - // TODO - Complete implementation - return KR_ERROR_NOT_IMPLEMENTED; + + return KR_SUCCESS; #else // Not implemented for this platform return KR_ERROR_NOT_IMPLEMENTED; @@ -816,6 +854,15 @@ KrResult KRContext::deleteWindowSurface(const KrDeleteWindowSurfaceInfo* deleteW if (deleteWindowSurfaceInfo->surfaceHandle < 0) { return KR_ERROR_OUT_OF_BOUNDS; } - // TODO - Complete implementation - return KR_ERROR_NOT_IMPLEMENTED; + if (m_vulkanInstance == VK_NULL_HANDLE) { + return KR_ERROR_VULKAN_REQUIRED; + } + auto itr = m_surfaces.find(deleteWindowSurfaceInfo->surfaceHandle); + if (itr == m_surfaces.end()) { + return KR_ERROR_NOT_FOUND; + } + SurfaceInfo* surfaceInfo = &(*itr).second; + vkDestroySurfaceKHR(m_vulkanInstance, surfaceInfo->surface, nullptr); + m_surfaces.erase(itr); + return KR_SUCCESS; } diff --git a/kraken/KRContext.h b/kraken/KRContext.h index 84537b7..8217b6c 100755 --- a/kraken/KRContext.h +++ b/kraken/KRContext.h @@ -171,10 +171,12 @@ private: void createDeviceContexts(); void destroyDeviceContexts(); + void destroySurfaces(); unordered_multimap m_resources; typedef struct { KrSurfaceHandle surfaceHandle; + VkSurfaceKHR surface; #ifdef WIN32 HWND hWnd; #endif diff --git a/kraken/kraken.cpp b/kraken/kraken.cpp index 3a1d4e7..a648dbc 100644 --- a/kraken/kraken.cpp +++ b/kraken/kraken.cpp @@ -42,20 +42,20 @@ KrResult KrShutdown() return KR_SUCCESS; } -KrResult KrCreateSurface(const KrCreateWindowSurfaceInfo* pCreateSurfaceInfo) +KrResult KrCreateWindowSurface(const KrCreateWindowSurfaceInfo* pCreateWindowSurfaceInfo) { if (!sContext) { return KR_ERROR_NOT_INITIALIZED; } - return sContext->createWindowSurface(pCreateSurfaceInfo); + return sContext->createWindowSurface(pCreateWindowSurfaceInfo); } -KrResult KrDeleteSurface(const KrDeleteWindowSurfaceInfo* pDeleteSurfaceInfo) +KrResult KrDeleteWindowSurface(const KrDeleteWindowSurfaceInfo* pDeleteWindowSurfaceInfo) { if (!sContext) { return KR_ERROR_NOT_INITIALIZED; } - return sContext->deleteWindowSurface(pDeleteSurfaceInfo); + return sContext->deleteWindowSurface(pDeleteWindowSurfaceInfo); } KrResult KrLoadResource(const KrLoadResourceInfo* pLoadResourceInfo) diff --git a/kraken/public/kraken.h b/kraken/public/kraken.h index 44b631f..b1c414d 100644 --- a/kraken/public/kraken.h +++ b/kraken/public/kraken.h @@ -38,14 +38,16 @@ typedef enum { KR_SUCCESS = 0, - KR_ERROR_NOT_INITIALIZED = 1, - KR_ERROR_NOT_IMPLEMENTED = 2, - KR_ERROR_OUT_OF_BOUNDS = 3, - KR_ERROR_NOT_MAPPED = 4, - KR_ERROR_INCORRECT_TYPE = 5, - KR_ERROR_NOT_FOUND = 6, - KR_ERROR_AMBIGUOUS_MATCH = 7, - KR_ERROR_DUPLICATE_HANDLE = 8, + KR_ERROR_NOT_INITIALIZED, + KR_ERROR_NOT_IMPLEMENTED, + KR_ERROR_OUT_OF_BOUNDS, + KR_ERROR_NOT_MAPPED, + KR_ERROR_INCORRECT_TYPE, + KR_ERROR_NOT_FOUND, + KR_ERROR_AMBIGUOUS_MATCH, + KR_ERROR_DUPLICATE_HANDLE, + KR_ERROR_VULKAN, + KR_ERROR_VULKAN_REQUIRED, KR_ERROR_UNEXPECTED = 0x10000000, KR_RESULT_MAX_ENUM = 0x7FFFFFFF } KrResult; @@ -54,6 +56,9 @@ typedef enum { KR_STRUCTURE_TYPE_INITIALIZE = 0, KR_STRUCTURE_TYPE_SHUTDOWN, + KR_STRUCTURE_TYPE_CREATE_WINDOW_SURFACE, + KR_STRUCTURE_TYPE_DELETE_WINDOW_SURFACE, + KR_STRUCTURE_TYPE_LOAD_RESOURCE = 0x00010000, KR_STRUCTURE_TYPE_UNLOAD_RESOURCE, KR_STRUCTURE_TYPE_SAVE_RESOURCE, diff --git a/tests/smoke/hello_cube/main_win.cpp b/tests/smoke/hello_cube/main_win.cpp index 1fc0e2c..ba7f224 100644 --- a/tests/smoke/hello_cube/main_win.cpp +++ b/tests/smoke/hello_cube/main_win.cpp @@ -17,12 +17,14 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine if (!RegisterClass(&wc)) return 1; - if (!CreateWindow(wc.lpszClassName, + HWND hWnd = CreateWindow(wc.lpszClassName, L"Kraken Smoke: Cube", WS_OVERLAPPEDWINDOW | WS_VISIBLE, - 0, 0, 640, 480, 0, 0, hInstance, NULL)) - return 2; + 0, 0, 640, 480, 0, 0, hInstance, NULL); + if (!hWnd) { + return 2; + } KrInitializeInfo init_info = {}; init_info.sType = KR_STRUCTURE_TYPE_INITIALIZE; @@ -44,11 +46,34 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine return 1; } + KrCreateWindowSurfaceInfo create_surface_info = {}; + create_surface_info.sType = KR_STRUCTURE_TYPE_CREATE_WINDOW_SURFACE; + create_surface_info.surfaceHandle = 1; + create_surface_info.hWnd = static_cast(hWnd); + res = KrCreateWindowSurface(&create_surface_info); + if (res != KR_SUCCESS) { + //printf("Failed to create window surface.\n"); + KrShutdown(); + return 1; + } + smoke_load(); while (GetMessage(&msg, NULL, 0, 0) > 0) DispatchMessage(&msg); + // KrShutdown will delete the window surfaces for us; however, we + // include this here for code coverage in tests. + KrDeleteWindowSurfaceInfo delete_surface_info = {}; + delete_surface_info.sType = KR_STRUCTURE_TYPE_DELETE_WINDOW_SURFACE; + delete_surface_info.surfaceHandle = 1; + res = KrDeleteWindowSurface(&delete_surface_info); + if (res != KR_SUCCESS) { + //printf("Failed to delete window surface.\n"); + KrShutdown(); + return 1; + } + KrShutdown(); return 0;