win32: Add basic window setup and remove winit based surface function

This commit is contained in:
msiglreith 2017-11-24 00:02:39 +01:00
parent 3179b49398
commit 936b207418
4 changed files with 131 additions and 31 deletions

View file

@ -1,8 +1,13 @@
/// Sample code adopted from https://github.com/LunarG/VulkanSamples /// Sample code adopted from https://github.com/LunarG/VulkanSamples
#if defined(_WIN32)
#define VK_USE_PLATFORM_WIN32_KHR
#endif
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include "window.hpp"
extern "C" VkSurfaceKHR vkCreateSurfaceGFX(VkInstance); extern "C" VkSurfaceKHR vkCreateSurfaceGFX(VkInstance);
@ -24,8 +29,19 @@ int main() {
return -1; return -1;
} }
VkSurfaceKHR surface = vkCreateSurfaceGFX(instance); // Window initialization
printf("\tvkCreateSurfaceGFX\n"); Config config = { 10, 10, 800, 600 };
Window window = new_window(config);
#if defined(_WIN32)
VkSurfaceKHR surface;
VkWin32SurfaceCreateInfoKHR surface_info = {};
surface_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
surface_info.hinstance = window.instance;
surface_info.hwnd = window.window;
vkCreateWin32SurfaceKHR(instance, &surface_info, NULL, &surface);
#endif
printf("\tvkCreateSurfaceKHR\n");
uint32_t adapter_count = 1; uint32_t adapter_count = 1;
VkPhysicalDevice physical_devices[1] = {}; VkPhysicalDevice physical_devices[1] = {};
@ -144,6 +160,9 @@ int main() {
assert(!res); assert(!res);
// Some work... // Some work...
while(poll_events()) {
}
vkFreeCommandBuffers(device, cmd_pool, 1, &cmd_buffer); vkFreeCommandBuffers(device, cmd_pool, 1, &cmd_buffer);
vkDestroyCommandPool(device, cmd_pool, NULL); vkDestroyCommandPool(device, cmd_pool, NULL);

81
native/window.cpp Normal file
View file

@ -0,0 +1,81 @@
#include <stdio.h>
#include "window.hpp"
#if defined(_WIN32)
const char *CLASS_NAME = "PortabilityClass";
auto WINAPI window_func(HWND hwnd, UINT u_msg, WPARAM w_param, LPARAM l_param) -> LRESULT {
if (u_msg == WM_CLOSE) {
PostQuitMessage(0);
}
return DefWindowProc(hwnd, u_msg, w_param, l_param);
}
auto register_class(HINSTANCE hinstance) -> bool {
WNDCLASS wclass = {0};
wclass.style = CS_HREDRAW | CS_VREDRAW;
wclass.lpszClassName = CLASS_NAME;
wclass.hInstance = hinstance;
wclass.lpfnWndProc = window_func;
wclass.hCursor = LoadCursor(NULL, IDC_ARROW);
if(!RegisterClass(&wclass)) {
printf("Couldn't register window class");
return false;
}
return true;
}
auto new_window(Config config) -> Window {
auto hinstance = GetModuleHandle(0);
register_class(hinstance);
RECT rect;
rect.left = config.x; rect.right = config.x + config.width;
rect.top = config.y; rect.bottom = config.y + config.height;
AdjustWindowRectEx(&rect, 0, false, 0);
auto hwnd = ::CreateWindow(
CLASS_NAME,
"GfxPortability",
WS_THICKFRAME | WS_SYSMENU,
rect.left,
rect.top,
rect.right-rect.left,
rect.bottom-rect.top,
NULL,
NULL,
::GetModuleHandle(0),
NULL
);
if(!hwnd) {
printf("Couldn't create window! error: %d", ::GetLastError());
}
::ShowWindow(hwnd, SW_SHOWDEFAULT);
::UpdateWindow(hwnd);
Window window = { hinstance, hwnd };
return window;
}
auto poll_events() -> bool {
MSG msg;
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT) {
return false;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return true;
}
#endif

24
native/window.hpp Normal file
View file

@ -0,0 +1,24 @@
#pragma once
#include <stdint.h>
#if defined(_WIN32)
#include <windows.h>
#endif
struct Window {
#if defined(_WIN32)
HINSTANCE instance;
HWND window;
#endif
};
struct Config {
uint32_t x;
uint32_t y;
uint32_t width;
uint32_t height;
};
auto new_window(Config config) -> Window;
auto poll_events() -> bool;

View file

@ -5206,16 +5206,7 @@ extern "C" {
//NOTE: all *KHR types have to be pure `Handle` things for compatibility with //NOTE: all *KHR types have to be pure `Handle` things for compatibility with
//`VK_DEFINE_NON_DISPATCHABLE_HANDLE` used in `vulkan.h` //`VK_DEFINE_NON_DISPATCHABLE_HANDLE` used in `vulkan.h`
#[repr(C)] pub type VkSurfaceKHR = Handle<<B as hal::Backend>::Surface>;
pub struct VkSurfaceInner<Backend: hal::Backend> {
raw: Backend::Surface,
window: winit::Window,
events_loop: winit::EventsLoop,
}
pub type VkSurfaceKHR = Handle<VkSurfaceInner<B>>;
// TODO: temporary surface type, should be replacing `VkSurfaceKHR` in the future.
pub type VkSurfaceRawKHR = Handle<<B as hal::Backend>::Surface>;
pub const VkColorSpaceKHR_VK_COLOR_SPACE_BEGIN_RANGE_KHR: VkColorSpaceKHR = pub const VkColorSpaceKHR_VK_COLOR_SPACE_BEGIN_RANGE_KHR: VkColorSpaceKHR =
VkColorSpaceKHR::VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; VkColorSpaceKHR::VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
@ -5346,7 +5337,7 @@ pub extern fn vkGetPhysicalDeviceSurfaceSupportKHR(
pSupported: *mut VkBool32, pSupported: *mut VkBool32,
) -> VkResult { ) -> VkResult {
let family = &adapter.queue_families[queueFamilyIndex as usize]; let family = &adapter.queue_families[queueFamilyIndex as usize];
let supports = surface.raw.supports_queue_family(family); let supports = surface.supports_queue_family(family);
unsafe { *pSupported = supports as _ }; unsafe { *pSupported = supports as _ };
VkResult::VK_SUCCESS VkResult::VK_SUCCESS
} }
@ -5357,7 +5348,7 @@ pub extern fn vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
surface: VkSurfaceKHR, surface: VkSurfaceKHR,
pSurfaceCapabilities: *mut VkSurfaceCapabilitiesKHR, pSurfaceCapabilities: *mut VkSurfaceCapabilitiesKHR,
) -> VkResult { ) -> VkResult {
let (caps, _) = surface.raw.capabilities_and_formats(&adapter.physical_device); let (caps, _) = surface.capabilities_and_formats(&adapter.physical_device);
let output = VkSurfaceCapabilitiesKHR { let output = VkSurfaceCapabilitiesKHR {
minImageCount: caps.image_count.start, minImageCount: caps.image_count.start,
@ -5389,7 +5380,7 @@ pub extern fn vkGetPhysicalDeviceSurfaceFormatsKHR(
pSurfaceFormatCount: *mut u32, pSurfaceFormatCount: *mut u32,
pSurfaceFormats: *mut VkSurfaceFormatKHR, pSurfaceFormats: *mut VkSurfaceFormatKHR,
) -> VkResult { ) -> VkResult {
let (_, formats) = surface.raw.capabilities_and_formats(&adapter.physical_device); let (_, formats) = surface.capabilities_and_formats(&adapter.physical_device);
let output = unsafe { slice::from_raw_parts_mut(pSurfaceFormats, *pSurfaceFormatCount as usize) }; let output = unsafe { slice::from_raw_parts_mut(pSurfaceFormats, *pSurfaceFormatCount as usize) };
if output.len() > formats.len() { if output.len() > formats.len() {
@ -5425,21 +5416,6 @@ pub extern fn vkGetPhysicalDeviceSurfacePresentModesKHR(
VkResult::VK_SUCCESS VkResult::VK_SUCCESS
} }
/// This is an EXTRA function not in original vulkan.h
#[no_mangle]
pub extern fn vkCreateSurfaceGFX(instance: VkInstance) -> VkSurfaceKHR {
let events_loop = winit::EventsLoop::new();
let window = winit::Window::new(&events_loop).unwrap();
let inner = VkSurfaceInner {
raw: instance.create_surface(&window),
window: window,
events_loop: events_loop,
};
Handle::new(inner)
}
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct VkSwapchainKHR_T { pub struct VkSwapchainKHR_T {
@ -5825,7 +5801,7 @@ pub fn vkCreateWin32SurfaceKHR(
instance: VkInstance, instance: VkInstance,
pCreateInfos: *const VkWin32SurfaceCreateInfoKHR, pCreateInfos: *const VkWin32SurfaceCreateInfoKHR,
pAllocator: *const VkAllocationCallbacks, pAllocator: *const VkAllocationCallbacks,
pSurface: *mut VkSurfaceRawKHR, pSurface: *mut VkSurfaceKHR,
) -> VkResult { ) -> VkResult {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
{ {