mirror of
https://github.com/italicsjenga/portability.git
synced 2024-11-25 08:21:31 +11:00
win32: Add basic window setup and remove winit based surface function
This commit is contained in:
parent
3179b49398
commit
936b207418
|
@ -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
81
native/window.cpp
Normal 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
24
native/window.hpp
Normal 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;
|
34
src/lib.rs
34
src/lib.rs
|
@ -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")]
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue