diff --git a/GPU/GPU.cpp b/GPU/GPU.cpp index 0c509df0c7..5365e7dd42 100644 --- a/GPU/GPU.cpp +++ b/GPU/GPU.cpp @@ -59,6 +59,8 @@ bool GPU_Init(GraphicsContext *ctx) { SetGPU(new DIRECTX9_GPU(ctx)); #endif break; + case GPU_DIRECTX11: + return nullptr; case GPU_VULKAN: SetGPU(new GPU_Vulkan(ctx)); break; diff --git a/Windows/GPU/WindowsVulkanContext.cpp b/Windows/GPU/WindowsVulkanContext.cpp index 1e36cff290..b6462aa651 100644 --- a/Windows/GPU/WindowsVulkanContext.cpp +++ b/Windows/GPU/WindowsVulkanContext.cpp @@ -163,7 +163,8 @@ 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->InitObjects(hInst, hWnd, true); + g_Vulkan->InitSurfaceWin32(hInst, hWnd); + g_Vulkan->InitObjects(true); _CrtCheckMemory(); diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 365b03b47f..32c9b991ee 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -209,6 +209,8 @@ EXEC_AND_LIB_FILES := \ $(SRC)/GPU/GLES/FragmentShaderGenerator.cpp.arm \ $(SRC)/GPU/GLES/FragmentTestCache.cpp.arm \ $(SRC)/GPU/GLES/TextureScaler.cpp \ + $(SRC)/GPU/Vulkan/FramebufferVulkan.cpp \ + $(SRC)/GPU/Vulkan/GPU_Vulkan.cpp \ $(SRC)/GPU/Null/NullGpu.cpp \ $(SRC)/GPU/Software/Clipper.cpp \ $(SRC)/GPU/Software/Lighting.cpp \ diff --git a/android/jni/Locals.mk b/android/jni/Locals.mk index 327f81c1b4..67c19581f7 100644 --- a/android/jni/Locals.mk +++ b/android/jni/Locals.mk @@ -8,6 +8,7 @@ LOCAL_CPPFLAGS := -fno-exceptions -std=gnu++11 -fno-rtti -Wno-reorder -Wno-liter LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/../../Common \ $(LOCAL_PATH)/../.. \ + $(LOCAL_PATH)/../../ext \ $(LOCAL_PATH)/$(NATIVE)/base \ $(LOCAL_PATH)/$(NATIVE)/ext \ $(LOCAL_PATH)/$(NATIVE)/ext/libzip \ diff --git a/ext/native/thin3d/VulkanContext.cpp b/ext/native/thin3d/VulkanContext.cpp index 923ddfb857..4d47968627 100644 --- a/ext/native/thin3d/VulkanContext.cpp +++ b/ext/native/thin3d/VulkanContext.cpp @@ -323,8 +323,8 @@ void VulkanBeginCommandBuffer(VkCommandBuffer cmd) { assert(res == VK_SUCCESS); } -void VulkanContext::InitObjects(HINSTANCE hInstance, HWND hWnd, bool depthPresent) { - InitSurfaceAndQueue(hInstance, hWnd); +void VulkanContext::InitObjects(bool depthPresent) { + InitQueue(); InitCommandPool(); // Create frame data @@ -793,7 +793,8 @@ void VulkanContext::InitDepthStencilBuffer(VkCommandBuffer cmd) { assert(res == VK_SUCCESS); } -void VulkanContext::InitSurfaceAndQueue(HINSTANCE conn, HWND wnd) { +#ifdef _WIN32 +void VulkanContext::InitSurfaceWin32(HINSTANCE conn, HWND wnd) { connection = conn; window = wnd; @@ -804,20 +805,38 @@ void VulkanContext::InitSurfaceAndQueue(HINSTANCE conn, HWND wnd) { VkResult U_ASSERT_ONLY res; -#ifdef _WIN32 VkWin32SurfaceCreateInfoKHR win32; win32.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; + win32.pNext = nullptr; win32.flags = 0; win32.hwnd = wnd; win32.hinstance = conn; res = vkCreateWin32SurfaceKHR(instance_, &win32, nullptr, &surface); -#else // _WIN32 - res = vkCreateXcbSurfaceKHR(instance_, info.connection, info.window, NULL, &info.surface); -#endif // _WIN32 - assert(res == VK_SUCCESS); +} +#elif defined(ANDROID) +void VulkanContext::InitSurfaceAndroid(ANativeWindow *native_window, int width, int height) { + connection = conn; + window = wnd; + VkResult U_ASSERT_ONLY res; + + VkAndroidSurfaceCreateInfoKHR android; + android.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; + android.flags = 0; + android.window = native_window; + android.pNext = nullptr; + res = vkCreateAndroidSurfaceKHR(instance_, &android, nullptr, &surface); + + this->width = width; + this->height = height; + assert(res == VK_SUCCESS); +} + +#endif + +void VulkanContext::InitQueue() { // Iterate over each queue to learn whether it supports presenting: VkBool32* supportsPresent = new VkBool32[queue_count]; for (uint32_t i = 0; i < queue_count; i++) { @@ -863,7 +882,7 @@ void VulkanContext::InitSurfaceAndQueue(HINSTANCE conn, HWND wnd) { // Get the list of VkFormats that are supported: uint32_t formatCount; - res = fpGetPhysicalDeviceSurfaceFormatsKHR(physical_devices_[0], + VkResult res = fpGetPhysicalDeviceSurfaceFormatsKHR(physical_devices_[0], surface, &formatCount, NULL); assert(res == VK_SUCCESS); diff --git a/ext/native/thin3d/VulkanContext.h b/ext/native/thin3d/VulkanContext.h index 4588e57cd0..5d9d733359 100644 --- a/ext/native/thin3d/VulkanContext.h +++ b/ext/native/thin3d/VulkanContext.h @@ -36,7 +36,10 @@ #define NOMINMAX /* Don't let Windows define min() or max() */ #define APP_NAME_STR_LEN 80 #include -#else // _WIN32 +#elif defined(ANDROID) // _WIN32 +#include +#define VK_USE_PLATFORM_ANDROID_KHR +#else #define VK_USE_PLATFORM_XCB_KHR #include #endif // _WIN32 @@ -158,14 +161,22 @@ public: VkPipelineCache CreatePipelineCache(); - void InitSurfaceAndQueue(HINSTANCE conn, HWND wnd); +#ifdef _WIN32 + void InitSurfaceWin32(HINSTANCE conn, HWND wnd); +#elif ANDROID + void InitSurfaceAndroid(ANativeWindow *native_window, int width, int height); +#else + //void InitSurfaceAndQueueXcb(); +#error Vulkan not supported on this platform +#endif + void InitQueue(); + void InitObjects(bool depthPresent); void InitSwapchain(VkCommandBuffer cmd); void InitSurfaceRenderPass(bool include_depth, bool clear); void InitFramebuffers(bool include_depth); void InitDepthStencilBuffer(VkCommandBuffer cmd); void InitCommandPool(); - void InitObjects(HINSTANCE hInstance, HWND hWnd, bool depthPresent); void DestroyObjects(); void DestroySurfaceRenderPass(); @@ -244,7 +255,9 @@ private: #ifdef _WIN32 HINSTANCE connection; // hInstance - Windows Instance HWND window; // hWnd - window handle -#else // _WIN32 +#elif ANDROID // _WIN32 + ANativeWindow *native_window; +#else xcb_connection_t *connection; xcb_screen_t *screen; xcb_window_t window; @@ -295,7 +308,7 @@ private: // Manages flipping command buffers for the backbuffer render pass. // It is recommended to do the same for other rendering passes. struct FrameData { - FrameData() : fence(nullptr), hasInitCommands(false), cmdInit(nullptr), cmdBuf(nullptr) {} + FrameData() : hasInitCommands(false), cmdInit(nullptr), cmdBuf(nullptr) {} VkFence fence; bool hasInitCommands; @@ -462,7 +475,9 @@ public: offset_ += (numBytes + 3) & ~3; // Round up to 4 bytes. if (offset_ >= size_) { // For now. 4MB is not enough for God of War but lets start with smaller games :P +#ifdef _WIN32 DebugBreak(); +#endif } return out; }