Permalink
Browse files

Avoid including platform-specific headers in VulkanContext.h

  • Loading branch information...
hrydgard committed Dec 18, 2017
1 parent 525cce0 commit 2250ef799cad6e507bde4e2cebc2f1ab76c706f8
@@ -95,13 +95,13 @@ VulkanContext::VulkanContext() {
GetInstanceLayerExtensionList(nullptr, instance_extension_properties_);
}
VkResult VulkanContext::CreateInstance(const char *app_name, int app_ver, uint32_t flags) {
VkResult VulkanContext::CreateInstance(const CreateInfo &info) {
if (!vkCreateInstance) {
init_error_ = "Vulkan not loaded - can't create instance";
return VK_ERROR_INITIALIZATION_FAILED;
}
flags_ = flags;
flags_ = info.flags;
// List extensions to try to enable.
instance_extensions_enabled_.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
@@ -120,9 +120,9 @@ VkResult VulkanContext::CreateInstance(const char *app_name, int app_ver, uint32
}
VkApplicationInfo app_info { VK_STRUCTURE_TYPE_APPLICATION_INFO };
app_info.pApplicationName = app_name;
app_info.applicationVersion = app_ver;
app_info.pEngineName = app_name;
app_info.pApplicationName = info.app_name;
app_info.applicationVersion = info.app_ver;
app_info.pEngineName = info.app_name;
// Let's increment this when we make major engine/context changes.
app_info.engineVersion = 2;
app_info.apiVersion = VK_API_VERSION_1_0;
@@ -583,65 +583,61 @@ void VulkanContext::DestroyDebugMsgCallback() {
}
}
#ifdef _WIN32
void VulkanContext::InitSurfaceWin32(HINSTANCE conn, HWND wnd) {
connection = conn;
window = wnd;
ReinitSurfaceWin32();
void VulkanContext::InitSurface(WindowSystem winsys, void *data1, void *data2, int width, int height) {
winsys_ = winsys;
winsysData1_ = data1;
winsysData2_ = data2;
ReinitSurface(width, height);
}
void VulkanContext::ReinitSurfaceWin32() {
void VulkanContext::ReinitSurface(int width, int height) {
if (surface_ != VK_NULL_HANDLE) {
ILOG("Destroying Vulkan surface (%d, %d)", width_, height_);
vkDestroySurfaceKHR(instance_, surface_, nullptr);
surface_ = VK_NULL_HANDLE;
}
RECT rc;
GetClientRect(window, &rc);
width_ = rc.right - rc.left;
height_ = rc.bottom - rc.top;
VkResult U_ASSERT_ONLY res;
VkWin32SurfaceCreateInfoKHR win32 = { VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR };
win32.flags = 0;
win32.hwnd = window;
win32.hinstance = connection;
res = vkCreateWin32SurfaceKHR(instance_, &win32, nullptr, &surface_);
assert(res == VK_SUCCESS);
}
#elif defined(__ANDROID__)
void VulkanContext::InitSurfaceAndroid(ANativeWindow *wnd, int width, int height) {
native_window = wnd;
ReinitSurfaceAndroid(width, height);
}
void VulkanContext::ReinitSurfaceAndroid(int width, int height) {
if (surface_ != VK_NULL_HANDLE) {
ILOG("Destroying Android Vulkan surface (%d, %d)", width_, height_);
vkDestroySurfaceKHR(instance_, surface_, nullptr);
surface_ = VK_NULL_HANDLE;
ILOG("Creating Vulkan surface (%d, %d)", width, height);
switch (winsys_) {
#ifdef _WIN32
case WINDOWSYSTEM_WIN32:
{
HINSTANCE connection = (HINSTANCE)winsysData1_;
HWND window = (HWND)winsysData2_;
RECT rc;
GetClientRect(window, &rc);
width = rc.right - rc.left;
height = rc.bottom - rc.top;
VkWin32SurfaceCreateInfoKHR win32{ VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR };
win32.flags = 0;
win32.hwnd = window;
win32.hinstance = connection;
VkResult res = vkCreateWin32SurfaceKHR(instance_, &win32, nullptr, &surface_);
assert(res == VK_SUCCESS);
break;
}
#endif
#if defined(__ANDROID__)
case WINDOWSYSTEM_ANDROID:
{
ANativeWindow *wnd = (ANativeWindow *)winsysData1_;
VkAndroidSurfaceCreateInfoKHR android{ VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR };
android.flags = 0;
android.window = wnd;
VkResult res = vkCreateAndroidSurfaceKHR(instance_, &android, nullptr, &surface_);
assert(res == VK_SUCCESS);
break;
}
#endif
default:
_assert_msg_(G3D, false, "Vulkan support for chosen window system not implemented");
break;
}
VkResult U_ASSERT_ONLY res;
ILOG("Creating Android Vulkan surface (%d, %d)", width, height);
VkAndroidSurfaceCreateInfoKHR android = { VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR };
android.flags = 0;
android.window = native_window;
res = vkCreateAndroidSurfaceKHR(instance_, &android, nullptr, &surface_);
assert(res == VK_SUCCESS);
width_ = width;
height_ = height;
}
#endif
bool VulkanContext::InitQueue() {
// Iterate over each queue to learn whether it supports presenting:
@@ -732,11 +728,8 @@ bool VulkanContext::InitQueue() {
}
bool VulkanContext::InitSwapchain() {
VkResult U_ASSERT_ONLY res;
res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_devices_[physical_device_], surface_, &surfCapabilities_);
VkResult res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_devices_[physical_device_], surface_, &surfCapabilities_);
assert(res == VK_SUCCESS);
uint32_t presentModeCount;
res = vkGetPhysicalDeviceSurfacePresentModesKHR(physical_devices_[physical_device_], surface_, &presentModeCount, nullptr);
assert(res == VK_SUCCESS);
@@ -1,41 +1,16 @@
#ifndef UTIL_INIT
#define UTIL_INIT
#pragma once
#ifdef __ANDROID__
#undef NDEBUG // asserts
#endif
#include <cassert>
#include <string>
#include <vector>
#include <utility>
#include "base/logging.h"
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#define VK_USE_PLATFORM_WIN32_KHR
#define NOMINMAX /* Don't let Windows define min() or max() */
#define APP_NAME_STR_LEN 80
#include <Windows.h>
#elif defined(__ANDROID__) // _WIN32
#include <android/native_window_jni.h>
#define VK_USE_PLATFORM_ANDROID_KHR
#else
#define VK_USE_PLATFORM_XCB_KHR
#include <unistd.h>
#endif // _WIN32
#include "Common/Vulkan/VulkanLoader.h"
// Amount of time, in nanoseconds, to wait for a command buffer to complete
#define FENCE_TIMEOUT 10000000000
#if defined(NDEBUG) && defined(__GNUC__)
#define U_ASSERT_ONLY __attribute__((unused))
#else
#define U_ASSERT_ONLY
#endif
enum {
VULKAN_FLAG_VALIDATE = 1,
VULKAN_FLAG_PRESENT_MAILBOX = 2,
@@ -54,6 +29,15 @@ enum {
std::string VulkanVendorString(uint32_t vendorId);
// Not all will be usable on all platforms, of course...
enum WindowSystem {
#ifdef _WIN32
WINDOWSYSTEM_WIN32,
#endif
#ifdef __ANDROID__
WINDOWSYSTEM_ANDROID,
#endif
};
struct VulkanPhysicalDeviceInfo {
VkFormat preferredDepthStencilFormat;
@@ -117,7 +101,13 @@ class VulkanContext {
VulkanContext();
~VulkanContext();
VkResult CreateInstance(const char *app_name, int app_ver, uint32_t flags);
struct CreateInfo {
const char *app_name;
int app_ver;
uint32_t flags;
};
VkResult CreateInstance(const CreateInfo &info);
void DestroyInstance();
int GetBestPhysicalDevice();
@@ -134,13 +124,9 @@ class VulkanContext {
VkPipelineCache CreatePipelineCache();
#ifdef _WIN32
void InitSurfaceWin32(HINSTANCE conn, HWND wnd);
void ReinitSurfaceWin32();
#elif __ANDROID__
void InitSurfaceAndroid(ANativeWindow *native_window, int width, int height);
void ReinitSurfaceAndroid(int width, int height);
#endif
// The parameters are whatever the chosen window system wants.
void InitSurface(WindowSystem winsys, void *data1, void *data2, int width = -1, int height = -1);
void ReinitSurface(int width = -1, int height = -1);
bool InitQueue();
bool InitObjects();
bool InitSwapchain();
@@ -238,12 +224,11 @@ class VulkanContext {
bool CheckLayers(const std::vector<LayerProperties> &layer_props, const std::vector<const char *> &layer_names) const;
#ifdef _WIN32
HINSTANCE connection = nullptr; // hInstance - Windows Instance
HWND window = nullptr; // hWnd - window handle
#elif __ANDROID__ // _WIN32
ANativeWindow *native_window = nullptr;
#endif // _WIN32
WindowSystem winsys_;
// Don't use the real types here to avoid having to include platform-specific stuff
// that we really don't want in everything that uses VulkanContext.
void *winsysData1_;
void *winsysData2_;
VkInstance instance_ = VK_NULL_HANDLE;
VkDevice device_ = VK_NULL_HANDLE;
@@ -320,6 +305,3 @@ void finalize_glslang();
bool GLSLtoSPV(const VkShaderStageFlagBits shader_type, const char *pshader, std::vector<uint32_t> &spirv, std::string *errorMessage = nullptr);
const char *VulkanResultToString(VkResult res);
#endif // UTIL_INIT
@@ -21,9 +21,7 @@ void VulkanTexture::CreateMappableImage() {
vulkan_->Delete().QueueDeleteDeviceMemory(mappableMemory);
}
bool U_ASSERT_ONLY pass;
VkImageCreateInfo image_create_info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
VkImageCreateInfo image_create_info{ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
image_create_info.imageType = VK_IMAGE_TYPE_2D;
image_create_info.format = format_;
image_create_info.extent.width = tex_width;
@@ -40,7 +38,7 @@ void VulkanTexture::CreateMappableImage() {
image_create_info.flags = 0;
image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
VkMemoryAllocateInfo mem_alloc = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
VkMemoryAllocateInfo mem_alloc{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
mem_alloc.allocationSize = 0;
mem_alloc.memoryTypeIndex = 0;
@@ -55,7 +53,7 @@ void VulkanTexture::CreateMappableImage() {
mem_alloc.allocationSize = mem_reqs.size;
// Find the memory type that is host mappable.
pass = vulkan_->MemoryTypeFromProperties(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &mem_alloc.memoryTypeIndex);
bool pass = vulkan_->MemoryTypeFromProperties(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &mem_alloc.memoryTypeIndex);
assert(pass);
res = vkAllocateMemory(vulkan_->GetDevice(), &mem_alloc, NULL, &mappableMemory);
@@ -46,7 +46,7 @@
// and use the same render pass configuration (clear to black). However, we can later change this so we switch
// to a non-clearing render pass in buffered mode, which might be a tiny bit faster.
#include <assert.h>
#include <cassert>
#include <crtdbg.h>
#include <sstream>
@@ -93,13 +93,15 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m
g_Vulkan = nullptr;
return false;
}
// int vulkanFlags = VULKAN_FLAG_PRESENT_FIFO_RELAXED;
int vulkanFlags = VULKAN_FLAG_PRESENT_MAILBOX;
VulkanContext::CreateInfo info{};
info.app_name = "PPSSPP";
info.app_ver = gitVer.ToInteger();
info.flags = VULKAN_FLAG_PRESENT_MAILBOX;
if (g_validate_) {
vulkanFlags |= VULKAN_FLAG_VALIDATE;
info.flags |= VULKAN_FLAG_VALIDATE;
}
if (VK_SUCCESS != g_Vulkan->CreateInstance("PPSSPP", gitVer.ToInteger(), vulkanFlags)) {
if (VK_SUCCESS != g_Vulkan->CreateInstance(info)) {
*error_message = g_Vulkan->InitError();
delete g_Vulkan;
g_Vulkan = nullptr;
@@ -119,7 +121,7 @@ bool WindowsVulkanContext::Init(HINSTANCE hInst, HWND hWnd, std::string *error_m
int bits = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
g_Vulkan->InitDebugMsgCallback(&Vulkan_Dbg, bits, &g_LogOptions);
}
g_Vulkan->InitSurfaceWin32(hInst, hWnd);
g_Vulkan->InitSurface(WINDOWSYSTEM_WIN32, (void *)hInst, (void *)hWnd);
if (!g_Vulkan->InitObjects()) {
*error_message = g_Vulkan->InitError();
Shutdown();
@@ -160,22 +162,16 @@ void WindowsVulkanContext::Shutdown() {
finalize_glslang();
}
void WindowsVulkanContext::SwapBuffers() {
}
void WindowsVulkanContext::Resize() {
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
g_Vulkan->DestroyObjects();
g_Vulkan->ReinitSurfaceWin32();
g_Vulkan->ReinitSurface();
g_Vulkan->InitObjects();
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
}
void WindowsVulkanContext::SwapInterval(int interval) {
}
void *WindowsVulkanContext::GetAPIContext() {
return g_Vulkan;
}
@@ -26,8 +26,8 @@ class WindowsVulkanContext : public WindowsGraphicsContext {
WindowsVulkanContext() : draw_(nullptr) {}
bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override;
void Shutdown() override;
void SwapInterval(int interval) override;
void SwapBuffers() override;
void SwapInterval(int interval) override {}
void SwapBuffers() override {}
void Resize() override;
void *GetAPIContext();
Oops, something went wrong.

0 comments on commit 2250ef7

Please sign in to comment.