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
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define VK_USE_PLATFORM_WIN32_KHR
|
||||
#endif
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include "window.hpp"
|
||||
|
||||
extern "C" VkSurfaceKHR vkCreateSurfaceGFX(VkInstance);
|
||||
|
||||
|
@ -24,8 +29,19 @@ int main() {
|
|||
return -1;
|
||||
}
|
||||
|
||||
VkSurfaceKHR surface = vkCreateSurfaceGFX(instance);
|
||||
printf("\tvkCreateSurfaceGFX\n");
|
||||
// Window initialization
|
||||
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;
|
||||
VkPhysicalDevice physical_devices[1] = {};
|
||||
|
@ -144,6 +160,9 @@ int main() {
|
|||
assert(!res);
|
||||
|
||||
// Some work...
|
||||
while(poll_events()) {
|
||||
|
||||
}
|
||||
|
||||
vkFreeCommandBuffers(device, cmd_pool, 1, &cmd_buffer);
|
||||
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
|
||||
//`VK_DEFINE_NON_DISPATCHABLE_HANDLE` used in `vulkan.h`
|
||||
#[repr(C)]
|
||||
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 type VkSurfaceKHR = Handle<<B as hal::Backend>::Surface>;
|
||||
|
||||
pub const VkColorSpaceKHR_VK_COLOR_SPACE_BEGIN_RANGE_KHR: VkColorSpaceKHR =
|
||||
VkColorSpaceKHR::VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
||||
|
@ -5346,7 +5337,7 @@ pub extern fn vkGetPhysicalDeviceSurfaceSupportKHR(
|
|||
pSupported: *mut VkBool32,
|
||||
) -> VkResult {
|
||||
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 _ };
|
||||
VkResult::VK_SUCCESS
|
||||
}
|
||||
|
@ -5357,7 +5348,7 @@ pub extern fn vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
|
|||
surface: VkSurfaceKHR,
|
||||
pSurfaceCapabilities: *mut VkSurfaceCapabilitiesKHR,
|
||||
) -> VkResult {
|
||||
let (caps, _) = surface.raw.capabilities_and_formats(&adapter.physical_device);
|
||||
let (caps, _) = surface.capabilities_and_formats(&adapter.physical_device);
|
||||
|
||||
let output = VkSurfaceCapabilitiesKHR {
|
||||
minImageCount: caps.image_count.start,
|
||||
|
@ -5389,7 +5380,7 @@ pub extern fn vkGetPhysicalDeviceSurfaceFormatsKHR(
|
|||
pSurfaceFormatCount: *mut u32,
|
||||
pSurfaceFormats: *mut VkSurfaceFormatKHR,
|
||||
) -> 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) };
|
||||
|
||||
if output.len() > formats.len() {
|
||||
|
@ -5425,21 +5416,6 @@ pub extern fn vkGetPhysicalDeviceSurfacePresentModesKHR(
|
|||
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)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct VkSwapchainKHR_T {
|
||||
|
@ -5825,7 +5801,7 @@ pub fn vkCreateWin32SurfaceKHR(
|
|||
instance: VkInstance,
|
||||
pCreateInfos: *const VkWin32SurfaceCreateInfoKHR,
|
||||
pAllocator: *const VkAllocationCallbacks,
|
||||
pSurface: *mut VkSurfaceRawKHR,
|
||||
pSurface: *mut VkSurfaceKHR,
|
||||
) -> VkResult {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue