mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-15 10:40:01 +01:00
Merge branch 'master' into TemporaryHackishBranch
# Conflicts: # UI/GameSettingsScreen.cpp # Windows/EmuThread.cpp
This commit is contained in:
commit
444832a0b2
34 files changed
+789
-609
No files matched your search
+71
-36
@@ -13,12 +13,6 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
|
||||
|
||||
add_definitions(-D__STDC_CONSTANT_MACROS)
|
||||
|
||||
# Of the CMake platforms, we only support Vulkan on Android and Windows.
|
||||
if(ANDROID OR WIN32)
|
||||
set(VULKAN ON)
|
||||
else()
|
||||
add_definitions(-DNO_VULKAN)
|
||||
endif()
|
||||
|
||||
if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
|
||||
set(CLANG ON)
|
||||
@@ -72,7 +66,33 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
endif()
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Android")
|
||||
set(ANDROID ON)
|
||||
set(ANDROID ON)
|
||||
endif()
|
||||
|
||||
# Of the CMake platforms, we only support Vulkan on Android and Windows.
|
||||
if(ANDROID OR WIN32 OR LINUX)
|
||||
set(VULKAN ON)
|
||||
else()
|
||||
add_definitions(-DNO_VULKAN)
|
||||
endif()
|
||||
|
||||
if(NOT ANDROID)
|
||||
# Use FindVulkan module added with CMAKE 3.7
|
||||
if (NOT CMAKE_VERSION VERSION_LESS 3.7.0)
|
||||
message(STATUS "Using module to find Vulkan")
|
||||
find_package(Vulkan)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT WIN32 AND VULKAN)
|
||||
IF (NOT Vulkan_FOUND)
|
||||
find_library(Vulkan_LIBRARY NAMES vulkan HINTS "$ENV{VULKAN_SDK}/lib" "${CMAKE_SOURCE_DIR}/ext/vulkan" REQUIRED)
|
||||
IF (Vulkan_LIBRARY)
|
||||
set(Vulkan_FOUND ON)
|
||||
MESSAGE("Using bundled Vulkan library version")
|
||||
add_definitions(-DVULKAN_STATIC)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED HEADLESS)
|
||||
@@ -86,6 +106,12 @@ else()
|
||||
message("Normal Build")
|
||||
endif()
|
||||
|
||||
if(LINUX AND VULKAN)
|
||||
message("Using XCB extension...")
|
||||
add_definitions(-DVK_USE_PLATFORM_XLIB_KHR)
|
||||
# add_definitions(-DVK_USE_PLATFORM_XCB_KHR)
|
||||
endif()
|
||||
|
||||
# Doesn't link on some platforms
|
||||
#if(NOT DEFINED UNITTEST)
|
||||
# set(UNITTEST OFF)
|
||||
@@ -113,6 +139,10 @@ option(SIMULATOR "Set to ON when targeting an x86 simulator of an ARM platform"
|
||||
option(USE_FFMPEG "Build with FFMPEG support" ${USE_FFMPEG})
|
||||
option(USE_SYSTEM_FFMPEG "Dynamically link against system FFMPEG" ${USE_SYSTEM_FFMPEG})
|
||||
|
||||
# Vulkan on Linux options. If none of these are set, X11 is assumed.
|
||||
OPTION(USE_D2D_WSI "Build the project using Direct to Display swapchain" OFF)
|
||||
OPTION(USE_WAYLAND_WSI "Build the project using Wayland swapchain" OFF)
|
||||
|
||||
if(ANDROID)
|
||||
set(CoreLibName ppsspp_jni)
|
||||
set(CoreLinkType SHARED)
|
||||
@@ -130,7 +160,10 @@ if(NOT OPENGL_LIBRARIES AND USING_GLES2)
|
||||
endif()
|
||||
|
||||
if(USING_EGL)
|
||||
set(OPENGL_LIBRARIES ${OPENGL_LIBRARIES} EGL)
|
||||
if(NOT EGL_LIBRARIES)
|
||||
set(EGL_LIBRARIES EGL)
|
||||
endif()
|
||||
set(OPENGL_LIBRARIES ${OPENGL_LIBRARIES} ${EGL_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(NOT OPENGL_LIBRARIES)
|
||||
@@ -322,23 +355,19 @@ set(CommonWindows
|
||||
Common/stdafx.h)
|
||||
source_group(Windows FILES ${CommonWindows})
|
||||
|
||||
if(VULKAN)
|
||||
set(CommonVulkan ${CommonExtra}
|
||||
Common/Vulkan/SPIRVDisasm.cpp
|
||||
Common/Vulkan/SPIRVDisasm.h
|
||||
Common/Vulkan/VulkanContext.cpp
|
||||
Common/Vulkan/VulkanContext.h
|
||||
Common/Vulkan/VulkanDebug.cpp
|
||||
Common/Vulkan/VulkanDebug.h
|
||||
Common/Vulkan/VulkanImage.cpp
|
||||
Common/Vulkan/VulkanImage.h
|
||||
Common/Vulkan/VulkanLoader.cpp
|
||||
Common/Vulkan/VulkanLoader.h
|
||||
Common/Vulkan/VulkanMemory.cpp
|
||||
Common/Vulkan/VulkanMemory.h)
|
||||
else()
|
||||
set(CommonVulkan)
|
||||
endif()
|
||||
set(CommonVulkan ${CommonExtra}
|
||||
Common/Vulkan/SPIRVDisasm.cpp
|
||||
Common/Vulkan/SPIRVDisasm.h
|
||||
Common/Vulkan/VulkanContext.cpp
|
||||
Common/Vulkan/VulkanContext.h
|
||||
Common/Vulkan/VulkanDebug.cpp
|
||||
Common/Vulkan/VulkanDebug.h
|
||||
Common/Vulkan/VulkanImage.cpp
|
||||
Common/Vulkan/VulkanImage.h
|
||||
Common/Vulkan/VulkanLoader.cpp
|
||||
Common/Vulkan/VulkanLoader.h
|
||||
Common/Vulkan/VulkanMemory.cpp
|
||||
Common/Vulkan/VulkanMemory.h)
|
||||
|
||||
add_library(Common STATIC
|
||||
${CommonX86}
|
||||
@@ -696,8 +725,8 @@ elseif(USING_QT_UI)
|
||||
qt5_wrap_ui(QT_UI_GEN ${Qt_UI})
|
||||
list(APPEND NativeAppSource
|
||||
${QT_UI_GEN}
|
||||
ext/native/base/QtMain.cpp
|
||||
ext/native/base/QtMain.h
|
||||
Qt/QtMain.cpp
|
||||
Qt/QtMain.h
|
||||
Qt/mainwindow.cpp
|
||||
Qt/mainwindow.h
|
||||
Qt/Debugger/ctrldisasmview.cpp
|
||||
@@ -742,16 +771,13 @@ elseif(TARGET SDL2::SDL2)
|
||||
set(nativeExtra ${nativeExtra}
|
||||
SDL/SDLJoystick.h
|
||||
SDL/SDLJoystick.cpp
|
||||
ext/native/base/PCMain.cpp)
|
||||
SDL/SDLMain.cpp)
|
||||
set(nativeExtraLibs ${nativeExtraLibs} SDL2::SDL2)
|
||||
if(APPLE)
|
||||
set(nativeExtra ${nativeExtra} SDL/SDLMain.h SDL/SDLMain.mm)
|
||||
set(nativeExtraLibs ${nativeExtraLibs} ${COCOA_LIBRARY})
|
||||
elseif(USING_EGL)
|
||||
if(NOT EGL_LIBRARIES)
|
||||
set(EGL_LIBRARIES EGL)
|
||||
endif()
|
||||
set(nativeExtraLibs ${nativeExtraLibs} pthread ${EGL_LIBRARIES})
|
||||
set(nativeExtraLibs ${nativeExtraLibs} pthread)
|
||||
endif()
|
||||
set(TargetBin PPSSPPSDL)
|
||||
elseif(WIN32)
|
||||
@@ -808,15 +834,14 @@ if(ANDROID)
|
||||
endif()
|
||||
|
||||
set(THIN3D_PLATFORMS ext/native/thin3d/thin3d_gl.cpp)
|
||||
if(VULKAN)
|
||||
set(THIN3D_PLATFORMS ${THIN3D_PLATFORMS}
|
||||
ext/native/thin3d/thin3d_vulkan.cpp
|
||||
set(THIN3D_PLATFORMS ${THIN3D_PLATFORMS}
|
||||
ext/native/thin3d/thin3d_vulkan.cpp
|
||||
ext/native/thin3d/VulkanRenderManager.cpp
|
||||
ext/native/thin3d/VulkanRenderManager.h
|
||||
ext/native/thin3d/VulkanQueueRunner.cpp
|
||||
ext/native/thin3d/VulkanQueueRunner.h
|
||||
ext/native/thin3d/DataFormat.h)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(THIN3D_PLATFORMS ${THIN3D_PLATFORMS}
|
||||
ext/native/thin3d/thin3d_d3d9.cpp
|
||||
@@ -1640,11 +1665,21 @@ endif()
|
||||
|
||||
set(CoreExtraLibs ${CoreExtraLibs} armips)
|
||||
|
||||
# needed for VK_USE_PLATFORM_XCB_KHR only
|
||||
#if(VULKAN AND NOT WIN32)
|
||||
# target_link_libraries(native X11-xcb X11)
|
||||
#endif()
|
||||
|
||||
|
||||
set(GlslangLibs glslang OGLCompiler OSDependent SPIRV SPVRemapper spirv-cross-glsl)
|
||||
|
||||
target_link_libraries(${CoreLibName} Common native kirk cityhash sfmt19937 xbrz xxhash ${GlslangLibs}
|
||||
${CoreExtraLibs} ${OPENGL_LIBRARIES} ${X11_LIBRARIES} ${CMAKE_DL_LIBS})
|
||||
|
||||
if(VULKAN)
|
||||
target_link_libraries(${CoreLibName} ${Vulkan_LIBRARY})
|
||||
endif()
|
||||
|
||||
if(FFmpeg_FOUND)
|
||||
target_compile_definitions(${CoreLibName} PRIVATE USE_FFMPEG=1)
|
||||
target_link_libraries(${CoreLibName}
|
||||
|
||||
@@ -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);
|
||||
@@ -109,6 +109,16 @@ VkResult VulkanContext::CreateInstance(const char *app_name, int app_ver, uint32
|
||||
instance_extensions_enabled_.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
|
||||
#elif defined(__ANDROID__)
|
||||
instance_extensions_enabled_.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
|
||||
#elif defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
instance_extensions_enabled_.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
|
||||
#elif defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
instance_extensions_enabled_.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
|
||||
#elif defined(VK_USE_PLATFORM_MIR_KHR)
|
||||
instance_extensions_enabled_.push_back(VK_KHR_MIR_SURFACE_EXTENSION_NAME);
|
||||
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
|
||||
instance_extensions.enabled_.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
|
||||
#else
|
||||
//...
|
||||
#endif
|
||||
|
||||
if (flags_ & VULKAN_FLAG_VALIDATE) {
|
||||
@@ -120,9 +130,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;
|
||||
@@ -424,6 +434,7 @@ int VulkanContext::GetBestPhysicalDevice() {
|
||||
|
||||
void VulkanContext::ChooseDevice(int physical_device) {
|
||||
physical_device_ = physical_device;
|
||||
ILOG("Chose physical device %d: %p", physical_device, physical_devices_[physical_device]);
|
||||
|
||||
GetDeviceLayerProperties();
|
||||
if (!CheckLayers(device_layer_properties_, device_layer_names_)) {
|
||||
@@ -545,6 +556,7 @@ VkResult VulkanContext::CreateDevice() {
|
||||
} else {
|
||||
VulkanLoadDeviceFunctions(device_);
|
||||
}
|
||||
ILOG("Device created.\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -563,7 +575,7 @@ VkResult VulkanContext::InitDebugMsgCallback(PFN_vkDebugReportCallbackEXT dbgFun
|
||||
cb.flags = bits;
|
||||
cb.pfnCallback = dbgFunc;
|
||||
cb.pUserData = userdata;
|
||||
VkResult res = vkCreateDebugReportCallbackEXT(instance_, &cb, nullptr, &msg_callback);
|
||||
VkResult res = dyn_vkCreateDebugReportCallbackEXT(instance_, &cb, nullptr, &msg_callback);
|
||||
switch (res) {
|
||||
case VK_SUCCESS:
|
||||
msg_callbacks.push_back(msg_callback);
|
||||
@@ -578,70 +590,91 @@ VkResult VulkanContext::InitDebugMsgCallback(PFN_vkDebugReportCallbackEXT dbgFun
|
||||
|
||||
void VulkanContext::DestroyDebugMsgCallback() {
|
||||
while (msg_callbacks.size() > 0) {
|
||||
vkDestroyDebugReportCallbackEXT(instance_, msg_callbacks.back(), nullptr);
|
||||
dyn_vkDestroyDebugReportCallbackEXT(instance_, msg_callbacks.back(), nullptr);
|
||||
msg_callbacks.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanContext::InitSurface(WindowSystem winsys, void *data1, void *data2, int width, int height) {
|
||||
winsys_ = winsys;
|
||||
winsysData1_ = data1;
|
||||
winsysData2_ = data2;
|
||||
ReinitSurface(width, height);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ILOG("Creating Vulkan surface (%d, %d)", width, height);
|
||||
switch (winsys_) {
|
||||
#ifdef _WIN32
|
||||
void VulkanContext::InitSurfaceWin32(HINSTANCE conn, HWND wnd) {
|
||||
connection = conn;
|
||||
window = wnd;
|
||||
case WINDOWSYSTEM_WIN32:
|
||||
{
|
||||
HINSTANCE connection = (HINSTANCE)winsysData1_;
|
||||
HWND window = (HWND)winsysData2_;
|
||||
|
||||
ReinitSurfaceWin32();
|
||||
}
|
||||
RECT rc;
|
||||
GetClientRect(window, &rc);
|
||||
width = rc.right - rc.left;
|
||||
height = rc.bottom - rc.top;
|
||||
|
||||
void VulkanContext::ReinitSurfaceWin32() {
|
||||
if (surface_ != VK_NULL_HANDLE) {
|
||||
vkDestroySurfaceKHR(instance_, surface_, nullptr);
|
||||
surface_ = VK_NULL_HANDLE;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
#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
|
||||
#if defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
case WINDOWSYSTEM_XLIB:
|
||||
{
|
||||
VkXlibSurfaceCreateInfoKHR xlib = { VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR };
|
||||
xlib.flags = 0;
|
||||
xlib.dpy = (Display *)winsysData1_;
|
||||
xlib.window = (Window)winsysData2_;
|
||||
VkResult res = vkCreateXlibSurfaceKHR(instance_, &xlib, nullptr, &surface_);
|
||||
assert(res == VK_SUCCESS);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
case WINDOWSYSTEM_XCB:
|
||||
{
|
||||
VkXCBSurfaceCreateInfoKHR xcb = { VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR };
|
||||
xcb.flags = 0;
|
||||
xcb.connection = (Connection *)winsysData1_;
|
||||
xcb.window = (Window)(uintptr_t)winsysData2_;
|
||||
VkResult res = vkCreateXcbSurfaceKHR(instance_, &xcb, nullptr, &surface_);
|
||||
assert(res == VK_SUCCESS);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
default:
|
||||
_assert_msg_(G3D, false, "Vulkan support for chosen window system not implemented");
|
||||
break;
|
||||
}
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool VulkanContext::InitQueue() {
|
||||
// Iterate over each queue to learn whether it supports presenting:
|
||||
@@ -688,16 +721,17 @@ bool VulkanContext::InitQueue() {
|
||||
graphics_queue_family_index_ = graphicsQueueNodeIndex;
|
||||
|
||||
// Get the list of VkFormats that are supported:
|
||||
uint32_t formatCount;
|
||||
uint32_t formatCount = 0;
|
||||
VkResult res = vkGetPhysicalDeviceSurfaceFormatsKHR(physical_devices_[physical_device_], surface_, &formatCount, nullptr);
|
||||
assert(res == VK_SUCCESS);
|
||||
if (res != VK_SUCCESS)
|
||||
_assert_msg_(G3D, res == VK_SUCCESS, "Failed to get formats for device %p: %d surface: %p", physical_devices_[physical_device_], (int)res, surface_);
|
||||
if (res != VK_SUCCESS) {
|
||||
return false;
|
||||
VkSurfaceFormatKHR *surfFormats = new VkSurfaceFormatKHR[formatCount];
|
||||
res = vkGetPhysicalDeviceSurfaceFormatsKHR(physical_devices_[physical_device_], surface_, &formatCount, surfFormats);
|
||||
}
|
||||
|
||||
std::vector<VkSurfaceFormatKHR> surfFormats(formatCount);
|
||||
res = vkGetPhysicalDeviceSurfaceFormatsKHR(physical_devices_[physical_device_], surface_, &formatCount, surfFormats.data());
|
||||
assert(res == VK_SUCCESS);
|
||||
if (res != VK_SUCCESS) {
|
||||
delete[] surfFormats;
|
||||
return false;
|
||||
}
|
||||
// If the format list includes just one entry of VK_FORMAT_UNDEFINED,
|
||||
@@ -724,7 +758,6 @@ bool VulkanContext::InitQueue() {
|
||||
}
|
||||
ILOG("swapchain_format: %d (/%d)", swapchainFormat_, formatCount);
|
||||
}
|
||||
delete[] surfFormats;
|
||||
|
||||
vkGetDeviceQueue(device_, graphics_queue_family_index_, 0, &gfx_queue_);
|
||||
ILOG("gfx_queue_: %p", gfx_queue_);
|
||||
@@ -732,11 +765,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,21 @@ 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
|
||||
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
||||
WINDOWSYSTEM_XLIB,
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||
WINDOWSYSTEM_XCB,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct VulkanPhysicalDeviceInfo {
|
||||
VkFormat preferredDepthStencilFormat;
|
||||
@@ -117,7 +107,13 @@ public:
|
||||
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 +130,10 @@ public:
|
||||
|
||||
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 +231,11 @@ private:
|
||||
|
||||
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;
|
||||
@@ -253,16 +245,16 @@ private:
|
||||
std::string init_error_;
|
||||
std::vector<const char *> instance_layer_names_;
|
||||
std::vector<LayerProperties> instance_layer_properties_;
|
||||
|
||||
|
||||
std::vector<const char *> instance_extensions_enabled_;
|
||||
std::vector<VkExtensionProperties> instance_extension_properties_;
|
||||
|
||||
std::vector<const char *> device_layer_names_;
|
||||
std::vector<LayerProperties> device_layer_properties_;
|
||||
|
||||
|
||||
std::vector<const char *> device_extensions_enabled_;
|
||||
std::vector<VkExtensionProperties> device_extension_properties_;
|
||||
|
||||
|
||||
std::vector<VkPhysicalDevice> physical_devices_;
|
||||
|
||||
int physical_device_ = -1;
|
||||
@@ -320,6 +312,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);
|
||||
@@ -264,23 +262,6 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write a command to transition the image to the requested layout, if it's not already that layout.
|
||||
if (initialLayout != VK_IMAGE_LAYOUT_UNDEFINED && initialLayout != VK_IMAGE_LAYOUT_PREINITIALIZED) {
|
||||
switch (initialLayout) {
|
||||
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
|
||||
TransitionImageLayout2(cmd, image, 0, numMips, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
0, VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||
break;
|
||||
default:
|
||||
// If you planned to use UploadMip, you want VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL. After the
|
||||
// upload, you can transition.
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
vkGetImageMemoryRequirements(vulkan_->GetDevice(), image, &mem_reqs);
|
||||
|
||||
if (allocator_) {
|
||||
@@ -313,6 +294,23 @@ bool VulkanTexture::CreateDirect(VkCommandBuffer cmd, int w, int h, int numMips,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write a command to transition the image to the requested layout, if it's not already that layout.
|
||||
if (initialLayout != VK_IMAGE_LAYOUT_UNDEFINED && initialLayout != VK_IMAGE_LAYOUT_PREINITIALIZED) {
|
||||
switch (initialLayout) {
|
||||
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
|
||||
TransitionImageLayout2(cmd, image, 0, numMips, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
0, VK_ACCESS_TRANSFER_WRITE_BIT);
|
||||
break;
|
||||
default:
|
||||
// If you planned to use UploadMip, you want VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL. After the
|
||||
// upload, you can transition.
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the view while we're at it.
|
||||
VkImageViewCreateInfo view_info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO };
|
||||
view_info.image = image;
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
|
||||
#include "Common/Vulkan/VulkanLoader.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/basictypes.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#ifndef VULKAN_STATIC
|
||||
|
||||
PFN_vkCreateInstance vkCreateInstance;
|
||||
PFN_vkDestroyInstance vkDestroyInstance;
|
||||
@@ -165,6 +167,8 @@ PFN_vkCmdExecuteCommands vkCmdExecuteCommands;
|
||||
PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR;
|
||||
#elif defined(_WIN32)
|
||||
PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;
|
||||
#elif defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR;
|
||||
#endif
|
||||
|
||||
PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
|
||||
@@ -179,10 +183,12 @@ PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
|
||||
PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
|
||||
PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
|
||||
PFN_vkQueuePresentKHR vkQueuePresentKHR;
|
||||
#endif
|
||||
|
||||
// And the DEBUG_REPORT extension. We dynamically load this.
|
||||
PFN_vkCreateDebugReportCallbackEXT dyn_vkCreateDebugReportCallbackEXT;
|
||||
PFN_vkDestroyDebugReportCallbackEXT dyn_vkDestroyDebugReportCallbackEXT;
|
||||
|
||||
// And the DEBUG_REPORT extension.
|
||||
PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT;
|
||||
PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT;
|
||||
|
||||
#ifdef _WIN32
|
||||
static HINSTANCE vulkanLibrary;
|
||||
@@ -195,15 +201,26 @@ static void *vulkanLibrary;
|
||||
#define LOAD_DEVICE_FUNC(instance, x) x = (PFN_ ## x)vkGetDeviceProcAddr(instance, #x); if (!x) {ILOG("Missing (device): %s", #x);}
|
||||
#define LOAD_GLOBAL_FUNC(x) x = (PFN_ ## x)dlsym(vulkanLibrary, #x); if (!x) {ILOG("Missing (global): %s", #x);}
|
||||
|
||||
static const char *so_names[] = {
|
||||
"libvulkan.so",
|
||||
"libvulkan.so.1",
|
||||
};
|
||||
|
||||
bool VulkanMayBeAvailable() {
|
||||
#ifdef VULKAN_STATIC
|
||||
return true;
|
||||
#else
|
||||
if (vulkanLibrary)
|
||||
return true;
|
||||
bool available = false;
|
||||
#ifndef _WIN32
|
||||
void *lib = dlopen("libvulkan.so", RTLD_NOW | RTLD_LOCAL);
|
||||
available = lib != nullptr;
|
||||
if (lib) {
|
||||
dlclose(lib);
|
||||
for (int i = 0; i < ARRAY_SIZE(so_names); i++) {
|
||||
void *lib = dlopen(so_names[i], RTLD_NOW | RTLD_LOCAL);
|
||||
if (lib) {
|
||||
available = true;
|
||||
dlclose(lib);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// LoadLibrary etc
|
||||
@@ -214,12 +231,18 @@ bool VulkanMayBeAvailable() {
|
||||
}
|
||||
#endif
|
||||
return available;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool VulkanLoad() {
|
||||
#ifndef VULKAN_STATIC
|
||||
if (!vulkanLibrary) {
|
||||
#ifndef _WIN32
|
||||
vulkanLibrary = dlopen("libvulkan.so", RTLD_NOW | RTLD_LOCAL);
|
||||
for (int i = 0; i < ARRAY_SIZE(so_names); i++) {
|
||||
vulkanLibrary = dlopen(so_names[i], RTLD_NOW | RTLD_LOCAL);
|
||||
if (vulkanLibrary)
|
||||
break;
|
||||
}
|
||||
#else
|
||||
// LoadLibrary etc
|
||||
vulkanLibrary = LoadLibrary(L"vulkan-1.dll");
|
||||
@@ -237,10 +260,12 @@ bool VulkanLoad() {
|
||||
LOAD_GLOBAL_FUNC(vkEnumerateInstanceLayerProperties);
|
||||
|
||||
WLOG("Vulkan base functions loaded.");
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void VulkanLoadInstanceFunctions(VkInstance instance) {
|
||||
#ifndef VULKAN_STATIC
|
||||
// OK, let's use the above functions to get the rest.
|
||||
LOAD_INSTANCE_FUNC(instance, vkDestroyInstance);
|
||||
LOAD_INSTANCE_FUNC(instance, vkEnumeratePhysicalDevices);
|
||||
@@ -374,7 +399,7 @@ void VulkanLoadInstanceFunctions(VkInstance instance) {
|
||||
LOAD_INSTANCE_FUNC(instance, vkCmdNextSubpass);
|
||||
LOAD_INSTANCE_FUNC(instance, vkCmdEndRenderPass);
|
||||
LOAD_INSTANCE_FUNC(instance, vkCmdExecuteCommands);
|
||||
|
||||
|
||||
LOAD_INSTANCE_FUNC(instance, vkGetPhysicalDeviceSurfaceSupportKHR);
|
||||
LOAD_INSTANCE_FUNC(instance, vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
|
||||
LOAD_INSTANCE_FUNC(instance, vkGetPhysicalDeviceSurfaceFormatsKHR);
|
||||
@@ -390,12 +415,16 @@ void VulkanLoadInstanceFunctions(VkInstance instance) {
|
||||
LOAD_INSTANCE_FUNC(instance, vkCreateWin32SurfaceKHR);
|
||||
#elif defined(__ANDROID__)
|
||||
LOAD_INSTANCE_FUNC(instance, vkCreateAndroidSurfaceKHR);
|
||||
#elif defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
LOAD_INSTANCE_FUNC(instance, vkCreateXlibSurfaceKHR);
|
||||
#endif
|
||||
|
||||
LOAD_INSTANCE_FUNC(instance, vkDestroySurfaceKHR);
|
||||
#endif
|
||||
|
||||
dyn_vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT");
|
||||
dyn_vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT");
|
||||
|
||||
LOAD_INSTANCE_FUNC(instance, vkCreateDebugReportCallbackEXT);
|
||||
LOAD_INSTANCE_FUNC(instance, vkDestroyDebugReportCallbackEXT);
|
||||
WLOG("Vulkan instance functions loaded.");
|
||||
}
|
||||
|
||||
@@ -404,15 +433,18 @@ void VulkanLoadInstanceFunctions(VkInstance instance) {
|
||||
// good for multi-device.
|
||||
void VulkanLoadDeviceFunctions(VkDevice device) {
|
||||
WLOG("Vulkan device functions loaded.");
|
||||
#ifndef VULKAN_STATIC
|
||||
// TODO: Move more functions VulkanLoadInstanceFunctions to here.
|
||||
LOAD_DEVICE_FUNC(device, vkCreateSwapchainKHR);
|
||||
LOAD_DEVICE_FUNC(device, vkDestroySwapchainKHR);
|
||||
LOAD_DEVICE_FUNC(device, vkGetSwapchainImagesKHR);
|
||||
LOAD_DEVICE_FUNC(device, vkAcquireNextImageKHR);
|
||||
LOAD_DEVICE_FUNC(device, vkQueuePresentKHR);
|
||||
#endif
|
||||
}
|
||||
|
||||
void VulkanFree() {
|
||||
#ifndef VULKAN_STATIC
|
||||
if (vulkanLibrary) {
|
||||
#ifdef _WIN32
|
||||
FreeLibrary(vulkanLibrary);
|
||||
@@ -421,4 +453,5 @@ void VulkanFree() {
|
||||
#endif
|
||||
vulkanLibrary = nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -25,10 +25,13 @@
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#ifndef VULKAN_STATIC
|
||||
#define VK_NO_PROTOTYPES
|
||||
#endif
|
||||
|
||||
#include "ext/vulkan/vulkan.h"
|
||||
|
||||
#ifndef VULKAN_STATIC
|
||||
extern PFN_vkCreateInstance vkCreateInstance;
|
||||
extern PFN_vkDestroyInstance vkDestroyInstance;
|
||||
extern PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
|
||||
@@ -171,6 +174,8 @@ extern PFN_vkCmdExecuteCommands vkCmdExecuteCommands;
|
||||
extern PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR;
|
||||
#elif defined(_WIN32)
|
||||
extern PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;
|
||||
#elif defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
extern PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR;
|
||||
#endif
|
||||
|
||||
extern PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
|
||||
@@ -187,9 +192,13 @@ extern PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
|
||||
extern PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
|
||||
extern PFN_vkQueuePresentKHR vkQueuePresentKHR;
|
||||
|
||||
// And the DEBUG_REPORT extension.
|
||||
extern PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT;
|
||||
extern PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT;
|
||||
#endif
|
||||
|
||||
// And the DEBUG_REPORT extension. Since we load this dynamically even in static
|
||||
// linked mode, we have to rename it :(
|
||||
extern PFN_vkCreateDebugReportCallbackEXT dyn_vkCreateDebugReportCallbackEXT;
|
||||
extern PFN_vkDestroyDebugReportCallbackEXT dyn_vkDestroyDebugReportCallbackEXT;
|
||||
|
||||
|
||||
// Way to do a quick check before even attempting to load.
|
||||
bool VulkanMayBeAvailable();
|
||||
@@ -198,4 +207,3 @@ bool VulkanLoad();
|
||||
void VulkanLoadInstanceFunctions(VkInstance instance);
|
||||
void VulkanLoadDeviceFunctions(VkDevice device);
|
||||
void VulkanFree();
|
||||
|
||||
+2
-5
@@ -531,12 +531,9 @@ static ConfigSetting graphicsSettings[] = {
|
||||
#endif
|
||||
ReportedConfigSetting("ForceMaxEmulatedFPS", &g_Config.iForceMaxEmulatedFPS, 60, true, true),
|
||||
|
||||
// TODO: Hm, on fast mobile GPUs we should definitely default to at least 4 (setting = 2)...
|
||||
#ifdef MOBILE_DEVICE
|
||||
ConfigSetting("AnisotropyLevel", &g_Config.iAnisotropyLevel, 0, true, true),
|
||||
#else
|
||||
// Most low-performance (and many high performance) mobile GPUs do not support aniso anyway so defaulting to 4 is fine.
|
||||
ConfigSetting("AnisotropyLevel", &g_Config.iAnisotropyLevel, 4, true, true),
|
||||
#endif
|
||||
|
||||
ReportedConfigSetting("VertexDecCache", &g_Config.bVertexCache, &DefaultVertexCache, true, true),
|
||||
ReportedConfigSetting("TextureBackoffCache", &g_Config.bTextureBackoffCache, false, true, true),
|
||||
ReportedConfigSetting("TextureSecondaryCache", &g_Config.bTextureSecondaryCache, false, true, true),
|
||||
|
||||
+30
-48
@@ -18,7 +18,9 @@
|
||||
#include "ppsspp_config.h"
|
||||
|
||||
#include <set>
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#include "base/NativeApp.h"
|
||||
#include "base/display.h"
|
||||
@@ -46,9 +48,9 @@
|
||||
// Should this be configurable? 2 hours currently.
|
||||
static const double ACTIVITY_IDLE_TIMEOUT = 2.0 * 3600.0;
|
||||
|
||||
static event m_hStepEvent;
|
||||
static std::condition_variable m_StepCond;
|
||||
static std::mutex m_hStepMutex;
|
||||
static event m_hInactiveEvent;
|
||||
static std::condition_variable m_InactiveCond;
|
||||
static std::mutex m_hInactiveMutex;
|
||||
static bool singleStepPending = false;
|
||||
static std::set<Core_ShutdownFunc> shutdownFuncs;
|
||||
@@ -95,7 +97,7 @@ void Core_Halt(const char *msg) {
|
||||
void Core_Stop() {
|
||||
Core_UpdateState(CORE_POWERDOWN);
|
||||
Core_NotifyShutdown();
|
||||
m_hStepEvent.notify_one();
|
||||
m_StepCond.notify_one();
|
||||
}
|
||||
|
||||
bool Core_IsStepping() {
|
||||
@@ -112,13 +114,15 @@ bool Core_IsInactive() {
|
||||
|
||||
void Core_WaitInactive() {
|
||||
while (Core_IsActive()) {
|
||||
m_hInactiveEvent.wait(m_hInactiveMutex);
|
||||
std::unique_lock<std::mutex> guard(m_hInactiveMutex);
|
||||
m_InactiveCond.wait(guard);
|
||||
}
|
||||
}
|
||||
|
||||
void Core_WaitInactive(int milliseconds) {
|
||||
if (Core_IsActive()) {
|
||||
m_hInactiveEvent.wait_for(m_hInactiveMutex, milliseconds);
|
||||
std::unique_lock<std::mutex> guard(m_hInactiveMutex);
|
||||
m_InactiveCond.wait_for(guard, std::chrono::milliseconds(milliseconds));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,11 +195,16 @@ void UpdateRunLoop() {
|
||||
}
|
||||
}
|
||||
|
||||
void KeepScreenAwake() {
|
||||
#ifdef _WIN32
|
||||
SetThreadExecutionState(ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Core_RunLoop(GraphicsContext *ctx) {
|
||||
graphicsContext = ctx;
|
||||
while ((GetUIState() != UISTATE_INGAME || !PSP_IsInited()) && GetUIState() != UISTATE_EXIT) {
|
||||
time_update();
|
||||
#if defined(USING_WIN_UI)
|
||||
double startTime = time_now_d();
|
||||
UpdateRunLoop();
|
||||
|
||||
@@ -204,19 +213,15 @@ void Core_RunLoop(GraphicsContext *ctx) {
|
||||
double diffTime = time_now_d() - startTime;
|
||||
int sleepTime = (int)(1000.0 / 60.0) - (int)(diffTime * 1000.0);
|
||||
if (sleepTime > 0)
|
||||
Sleep(sleepTime);
|
||||
sleep_ms(sleepTime);
|
||||
if (!windowHidden) {
|
||||
ctx->SwapBuffers();
|
||||
}
|
||||
#else
|
||||
UpdateRunLoop();
|
||||
#endif
|
||||
}
|
||||
|
||||
while (!coreState && GetUIState() == UISTATE_INGAME) {
|
||||
time_update();
|
||||
UpdateRunLoop();
|
||||
#if defined(USING_WIN_UI)
|
||||
if (!windowHidden && !Core_IsStepping()) {
|
||||
ctx->SwapBuffers();
|
||||
|
||||
@@ -226,22 +231,21 @@ void Core_RunLoop(GraphicsContext *ctx) {
|
||||
// Only resetting it ever prime number seconds in case the call is expensive.
|
||||
// Using a prime number to ensure there's no interaction with other periodic events.
|
||||
if (now - lastKeepAwake > 89.0 || now < lastKeepAwake) {
|
||||
SetThreadExecutionState(ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED);
|
||||
KeepScreenAwake();
|
||||
lastKeepAwake = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void Core_DoSingleStep() {
|
||||
singleStepPending = true;
|
||||
m_hStepEvent.notify_one();
|
||||
m_StepCond.notify_one();
|
||||
}
|
||||
|
||||
void Core_UpdateSingleStep() {
|
||||
m_hStepEvent.notify_one();
|
||||
m_StepCond.notify_one();
|
||||
}
|
||||
|
||||
void Core_SingleStep() {
|
||||
@@ -251,20 +255,15 @@ void Core_SingleStep() {
|
||||
static inline void CoreStateProcessed() {
|
||||
if (coreStatePending) {
|
||||
coreStatePending = false;
|
||||
m_hInactiveEvent.notify_one();
|
||||
m_InactiveCond.notify_one();
|
||||
}
|
||||
}
|
||||
|
||||
// Some platforms, like Android, do not call this function but handle things on their own.
|
||||
void Core_Run(GraphicsContext *ctx)
|
||||
{
|
||||
#if defined(_DEBUG)
|
||||
// Many platforms, like Android, do not call this function but handle things on their own.
|
||||
// Instead they simply call NativeRender and NativeUpdate directly.
|
||||
void Core_Run(GraphicsContext *ctx) {
|
||||
host->UpdateDisassembly();
|
||||
#endif
|
||||
#if !defined(USING_QT_UI) || defined(MOBILE_DEVICE)
|
||||
while (true)
|
||||
#endif
|
||||
{
|
||||
while (true) {
|
||||
reswitch:
|
||||
if (GetUIState() != UISTATE_INGAME) {
|
||||
CoreStateProcessed();
|
||||
@@ -272,15 +271,10 @@ reswitch:
|
||||
return;
|
||||
}
|
||||
Core_RunLoop(ctx);
|
||||
#if defined(USING_QT_UI) && !defined(MOBILE_DEVICE)
|
||||
return;
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
|
||||
switch (coreState)
|
||||
{
|
||||
switch (coreState) {
|
||||
case CORE_RUNNING:
|
||||
// enter a fast runloop
|
||||
Core_RunLoop(ctx);
|
||||
@@ -298,21 +292,16 @@ reswitch:
|
||||
}
|
||||
|
||||
// wait for step command..
|
||||
#if defined(USING_QT_UI) || defined(_DEBUG)
|
||||
host->UpdateDisassembly();
|
||||
host->UpdateMemView();
|
||||
host->SendCoreWait(true);
|
||||
#endif
|
||||
|
||||
m_hStepEvent.wait(m_hStepMutex);
|
||||
{
|
||||
std::unique_lock<std::mutex> guard(m_hStepMutex);
|
||||
m_StepCond.wait(guard);
|
||||
}
|
||||
|
||||
#if defined(USING_QT_UI) || defined(_DEBUG)
|
||||
host->SendCoreWait(false);
|
||||
#endif
|
||||
#if defined(USING_QT_UI) && !defined(MOBILE_DEVICE)
|
||||
if (coreState != CORE_STEPPING)
|
||||
return;
|
||||
#endif
|
||||
// No step pending? Let's go back to the wait.
|
||||
if (!singleStepPending || coreState != CORE_STEPPING) {
|
||||
if (coreState == CORE_POWERDOWN) {
|
||||
@@ -323,10 +312,8 @@ reswitch:
|
||||
|
||||
Core_SingleStep();
|
||||
// update disasm dialog
|
||||
#if defined(USING_QT_UI) || defined(_DEBUG)
|
||||
host->UpdateDisassembly();
|
||||
host->UpdateMemView();
|
||||
#endif
|
||||
break;
|
||||
|
||||
case CORE_POWERUP:
|
||||
@@ -346,17 +333,12 @@ reswitch:
|
||||
void Core_EnableStepping(bool step) {
|
||||
if (step) {
|
||||
sleep_ms(1);
|
||||
#if defined(_DEBUG)
|
||||
host->SetDebugMode(true);
|
||||
#endif
|
||||
m_hStepEvent.reset();
|
||||
Core_UpdateState(CORE_STEPPING);
|
||||
} else {
|
||||
#if defined(_DEBUG)
|
||||
host->SetDebugMode(false);
|
||||
#endif
|
||||
coreState = CORE_RUNNING;
|
||||
coreStatePending = false;
|
||||
m_hStepEvent.notify_one();
|
||||
m_StepCond.notify_one();
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "profiler/profiler.h"
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#include "Core/Reporting.h"
|
||||
|
||||
|
||||
@@ -24,8 +24,10 @@
|
||||
#include <string>
|
||||
#include <codecvt>
|
||||
#endif
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#include "math/math_util.h"
|
||||
#include "thread/threadutil.h"
|
||||
|
||||
@@ -910,12 +910,7 @@ void TextureCacheCommon::NotifyConfigChanged() {
|
||||
}
|
||||
}
|
||||
|
||||
// Mobile devices don't get the higher scale factors, too expensive. Very rough way to decide though...
|
||||
if (!gstate_c.Supports(GPU_IS_MOBILE)) {
|
||||
scaleFactor = std::min(5, scaleFactor);
|
||||
} else {
|
||||
scaleFactor = std::min(3, scaleFactor);
|
||||
}
|
||||
scaleFactor = std::min(5, scaleFactor);
|
||||
} else {
|
||||
scaleFactor = g_Config.iTexScalingLevel;
|
||||
}
|
||||
|
||||
@@ -342,11 +342,6 @@ void GPU_GLES::CheckGPUFeatures() {
|
||||
features |= GPU_USE_CLEAR_RAM_HACK;
|
||||
}
|
||||
|
||||
#ifdef MOBILE_DEVICE
|
||||
// Arguably, we should turn off GPU_IS_MOBILE on like modern Tegras, etc.
|
||||
features |= GPU_IS_MOBILE;
|
||||
#endif
|
||||
|
||||
gstate_c.featureFlags = features;
|
||||
}
|
||||
|
||||
|
||||
@@ -490,7 +490,6 @@ enum {
|
||||
GPU_SUPPORTS_ARB_FRAMEBUFFER_BLIT = FLAG_BIT(26),
|
||||
GPU_SUPPORTS_NV_FRAMEBUFFER_BLIT = FLAG_BIT(27),
|
||||
GPU_SUPPORTS_OES_TEXTURE_NPOT = FLAG_BIT(28),
|
||||
GPU_IS_MOBILE = FLAG_BIT(29),
|
||||
GPU_PREFER_CPU_DOWNLOAD = FLAG_BIT(30),
|
||||
GPU_PREFER_REVERSE_COLOR_ORDER = FLAG_BIT(31),
|
||||
};
|
||||
|
||||
@@ -173,27 +173,27 @@ bool GenerateVulkanGLSLVertexShader(const VShaderID &id, char *buffer, bool *use
|
||||
}
|
||||
|
||||
if (useHWTransform)
|
||||
WRITE(p, "layout (location = %d) in vec3 position;\n", PspAttributeLocation::POSITION);
|
||||
WRITE(p, "layout (location = %d) in vec3 position;\n", (int)PspAttributeLocation::POSITION);
|
||||
else
|
||||
// we pass the fog coord in w
|
||||
WRITE(p, "layout (location = %d) in vec4 position;\n", PspAttributeLocation::POSITION);
|
||||
WRITE(p, "layout (location = %d) in vec4 position;\n", (int)PspAttributeLocation::POSITION);
|
||||
|
||||
if (useHWTransform && hasNormal)
|
||||
WRITE(p, "layout (location = %d) in vec3 normal;\n", PspAttributeLocation::NORMAL);
|
||||
WRITE(p, "layout (location = %d) in vec3 normal;\n", (int)PspAttributeLocation::NORMAL);
|
||||
|
||||
bool texcoordInVec3 = false;
|
||||
if (doTexture && hasTexcoord) {
|
||||
if (!useHWTransform && doTextureTransform && !throughmode) {
|
||||
WRITE(p, "layout (location = %d) in vec3 texcoord;\n", PspAttributeLocation::TEXCOORD);
|
||||
WRITE(p, "layout (location = %d) in vec3 texcoord;\n", (int)PspAttributeLocation::TEXCOORD);
|
||||
texcoordInVec3 = true;
|
||||
}
|
||||
else
|
||||
WRITE(p, "layout (location = %d) in vec2 texcoord;\n", PspAttributeLocation::TEXCOORD);
|
||||
WRITE(p, "layout (location = %d) in vec2 texcoord;\n", (int)PspAttributeLocation::TEXCOORD);
|
||||
}
|
||||
if (hasColor) {
|
||||
WRITE(p, "layout (location = %d) in vec4 color0;\n", PspAttributeLocation::COLOR0);
|
||||
WRITE(p, "layout (location = %d) in vec4 color0;\n", (int)PspAttributeLocation::COLOR0);
|
||||
if (lmode && !useHWTransform) // only software transform supplies color1 as vertex data
|
||||
WRITE(p, "layout (location = %d) in vec3 color1;\n", PspAttributeLocation::COLOR1);
|
||||
WRITE(p, "layout (location = %d) in vec3 color1;\n", (int)PspAttributeLocation::COLOR1);
|
||||
}
|
||||
|
||||
WRITE(p, "layout (location = 1) %sout vec4 v_color0;\n", shading);
|
||||
|
||||
File renamed without changes.
File renamed without changes.
+1
-1
@@ -14,7 +14,7 @@
|
||||
#include "Debugger/debugger_memory.h"
|
||||
#include "Debugger/debugger_memorytex.h"
|
||||
#include "Debugger/debugger_displaylist.h"
|
||||
#include "base/QtMain.h"
|
||||
#include "Qt/QtMain.h"
|
||||
|
||||
extern bool g_TakeScreenshot;
|
||||
|
||||
|
||||
@@ -3,24 +3,12 @@
|
||||
// Note: SDL1.2 implementation is deprecated and will soon be replaced by SDL2.0.
|
||||
// If your platform is not supported, it is suggested to use Qt instead.
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning(disable:4091) // workaround bug in VS2015 headers
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <shlobj.h>
|
||||
#include <shlwapi.h>
|
||||
#include <ShellAPI.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
|
||||
#include "SDL.h"
|
||||
#ifndef _WIN32
|
||||
#include "SDL/SDLJoystick.h"
|
||||
SDLJoystick *joystick = NULL;
|
||||
#endif
|
||||
|
||||
#if PPSSPP_PLATFORM(RPI)
|
||||
#include <bcm_host.h>
|
||||
@@ -28,6 +16,7 @@ SDLJoystick *joystick = NULL;
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
|
||||
#include "base/display.h"
|
||||
#include "base/logging.h"
|
||||
@@ -41,34 +30,35 @@ SDLJoystick *joystick = NULL;
|
||||
#include "base/NKCodeFromSDL.h"
|
||||
#include "util/const_map.h"
|
||||
#include "util/text/utf8.h"
|
||||
#include "util/text/parsers.h"
|
||||
#include "math/math_util.h"
|
||||
#include "Common/Vulkan/VulkanContext.h"
|
||||
#include "Common/Vulkan/VulkanDebug.h"
|
||||
#include "math.h"
|
||||
|
||||
#if defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include "SDL_syswm.h"
|
||||
#elif defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xlib-xcb.h>
|
||||
#include "SDL_syswm.h"
|
||||
#endif
|
||||
|
||||
#if defined(USING_EGL)
|
||||
#include "EGL/egl.h"
|
||||
#endif
|
||||
|
||||
#include "Core/System.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Common/GraphicsContext.h"
|
||||
|
||||
class GLDummyGraphicsContext : public DummyGraphicsContext {
|
||||
public:
|
||||
GLDummyGraphicsContext() {
|
||||
CheckGLExtensions();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
bool success = draw_->CreatePresets();
|
||||
assert(success);
|
||||
}
|
||||
~GLDummyGraphicsContext() { delete draw_; }
|
||||
|
||||
Draw::DrawContext *GetDrawContext() override {
|
||||
return draw_;
|
||||
}
|
||||
private:
|
||||
Draw::DrawContext *draw_;
|
||||
};
|
||||
|
||||
GlobalUIState lastUIState = UISTATE_MENU;
|
||||
GlobalUIState GetUIState();
|
||||
|
||||
static SDL_Window* g_Screen = NULL;
|
||||
static bool g_ToggleFullScreenNextFrame = false;
|
||||
static int g_ToggleFullScreenType;
|
||||
static int g_QuitRequested = 0;
|
||||
@@ -76,16 +66,9 @@ static int g_QuitRequested = 0;
|
||||
static int g_DesktopWidth = 0;
|
||||
static int g_DesktopHeight = 0;
|
||||
|
||||
static VulkanLogOptions g_LogOptions;
|
||||
|
||||
#if defined(USING_EGL)
|
||||
#include "EGL/egl.h"
|
||||
|
||||
#if !defined(USING_FBDEV)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#endif
|
||||
|
||||
#include "SDL_syswm.h"
|
||||
#include "math.h"
|
||||
|
||||
static EGLDisplay g_eglDisplay = NULL;
|
||||
static EGLContext g_eglContext = NULL;
|
||||
@@ -172,16 +155,13 @@ int8_t EGL_Init() {
|
||||
g_eglContext = eglCreateContext(g_eglDisplay, g_eglConfig, NULL, attributes );
|
||||
if (g_eglContext == EGL_NO_CONTEXT) EGL_ERROR("Unable to create GLES context!", true);
|
||||
|
||||
#if !defined(USING_FBDEV)
|
||||
#if !defined(USING_FBDEV) && !defined(__APPLE__)
|
||||
//Get the SDL window handle
|
||||
SDL_SysWMinfo sysInfo; //Will hold our Window information
|
||||
SDL_VERSION(&sysInfo.version); //Set SDL version
|
||||
#endif
|
||||
|
||||
#ifdef USING_FBDEV
|
||||
g_Window = (NativeWindowType)NULL;
|
||||
#else
|
||||
g_Window = (NativeWindowType)sysInfo.info.x11.window;
|
||||
#else
|
||||
g_Window = (NativeWindowType)NULL;
|
||||
#endif
|
||||
g_eglSurface = eglCreateWindowSurface(g_eglDisplay, g_eglConfig, g_Window, 0);
|
||||
if (g_eglSurface == EGL_NO_SURFACE)
|
||||
@@ -216,6 +196,298 @@ void EGL_Close() {
|
||||
}
|
||||
#endif
|
||||
|
||||
class SDLGLGraphicsContext : public DummyGraphicsContext {
|
||||
public:
|
||||
SDLGLGraphicsContext() {
|
||||
}
|
||||
~SDLGLGraphicsContext() {
|
||||
delete draw_;
|
||||
}
|
||||
|
||||
// Returns 0 on success.
|
||||
int Init(SDL_Window *&window, int x, int y, int mode, std::string *error_message);
|
||||
|
||||
void Shutdown() override {
|
||||
#ifdef USING_EGL
|
||||
EGL_Close();
|
||||
#else
|
||||
SDL_GL_DeleteContext(glContext);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SwapBuffers() override {
|
||||
#ifdef USING_EGL
|
||||
eglSwapBuffers(g_eglDisplay, g_eglSurface);
|
||||
#else
|
||||
SDL_GL_SwapWindow(window_);
|
||||
#endif
|
||||
}
|
||||
|
||||
Draw::DrawContext *GetDrawContext() override {
|
||||
return draw_;
|
||||
}
|
||||
|
||||
private:
|
||||
Draw::DrawContext *draw_ = nullptr;
|
||||
SDL_Window *window_;
|
||||
SDL_GLContext glContext = nullptr;
|
||||
};
|
||||
|
||||
// Returns 0 on success.
|
||||
int SDLGLGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, std::string *error_message) {
|
||||
struct GLVersionPair {
|
||||
int major;
|
||||
int minor;
|
||||
};
|
||||
GLVersionPair attemptVersions[] = {
|
||||
#ifdef USING_GLES2
|
||||
{3, 2}, {3, 1}, {3, 0}, {2, 0},
|
||||
#else
|
||||
{4, 6}, {4, 5}, {4, 4}, {4, 3}, {4, 2}, {4, 1}, {4, 0},
|
||||
{3, 3}, {3, 2}, {3, 1}, {3, 0},
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef USING_GLES2
|
||||
mode |= SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN;
|
||||
#else
|
||||
mode |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
|
||||
#endif
|
||||
SDL_GLContext glContext = nullptr;
|
||||
for (size_t i = 0; i < ARRAY_SIZE(attemptVersions); ++i) {
|
||||
const auto &ver = attemptVersions[i];
|
||||
// Make sure to request a somewhat modern GL context at least - the
|
||||
// latest supported by MacOS X (really, really sad...)
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, ver.major);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, ver.minor);
|
||||
#ifdef USING_GLES2
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||
SetGLCoreContext(false);
|
||||
#else
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
SetGLCoreContext(true);
|
||||
#endif
|
||||
|
||||
window = SDL_CreateWindow("PPSSPP", x,y, pixel_xres, pixel_yres, mode);
|
||||
if (!window) {
|
||||
NativeShutdown();
|
||||
fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError());
|
||||
continue;
|
||||
}
|
||||
|
||||
glContext = SDL_GL_CreateContext(window);
|
||||
if (glContext != nullptr) {
|
||||
// Victory, got one.
|
||||
break;
|
||||
}
|
||||
|
||||
// Let's keep trying. To be safe, destroy the window - docs say needed to change profile.
|
||||
// in practice, it doesn't seem to matter, but maybe it differs by platform.
|
||||
SDL_DestroyWindow(window);
|
||||
}
|
||||
|
||||
if (glContext == nullptr) {
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
SetGLCoreContext(false);
|
||||
|
||||
window = SDL_CreateWindow("PPSSPP", x,y, pixel_xres, pixel_yres, mode);
|
||||
if (window == nullptr) {
|
||||
NativeShutdown();
|
||||
fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
return 2;
|
||||
}
|
||||
|
||||
glContext = SDL_GL_CreateContext(window);
|
||||
if (glContext == nullptr) {
|
||||
NativeShutdown();
|
||||
fprintf(stderr, "SDL_GL_CreateContext failed: %s\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USING_EGL
|
||||
EGL_Init();
|
||||
#endif
|
||||
|
||||
#ifndef USING_GLES2
|
||||
// Some core profile drivers elide certain extensions from GL_EXTENSIONS/etc.
|
||||
// glewExperimental allows us to force GLEW to search for the pointers anyway.
|
||||
if (gl_extensions.IsCoreContext) {
|
||||
glewExperimental = true;
|
||||
}
|
||||
if (GLEW_OK != glewInit()) {
|
||||
printf("Failed to initialize glew!\n");
|
||||
return 1;
|
||||
}
|
||||
// Unfortunately, glew will generate an invalid enum error, ignore.
|
||||
if (gl_extensions.IsCoreContext)
|
||||
glGetError();
|
||||
|
||||
if (GLEW_VERSION_2_0) {
|
||||
printf("OpenGL 2.0 or higher.\n");
|
||||
} else {
|
||||
printf("Sorry, this program requires OpenGL 2.0.\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Finally we can do the regular initialization.
|
||||
CheckGLExtensions();
|
||||
draw_ = Draw::T3DCreateGLContext();
|
||||
bool success = draw_->CreatePresets();
|
||||
assert(success);
|
||||
window_ = window;
|
||||
return 0;
|
||||
}
|
||||
|
||||
class SDLVulkanGraphicsContext : public GraphicsContext {
|
||||
public:
|
||||
SDLVulkanGraphicsContext() {}
|
||||
~SDLVulkanGraphicsContext() {
|
||||
delete draw_;
|
||||
}
|
||||
|
||||
bool Init(SDL_Window *&window, int x, int y, int mode, std::string *error_message);
|
||||
|
||||
void Shutdown() override;
|
||||
|
||||
void SwapBuffers() override {
|
||||
// We don't do it this way.
|
||||
}
|
||||
|
||||
void Resize() override {
|
||||
/*
|
||||
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());
|
||||
vulkan_->DestroyObjects();
|
||||
// TODO: Take from real window dimensions
|
||||
int width = 1024;
|
||||
int height = 768;
|
||||
vulkan_->ReinitSurface(width, height);
|
||||
vulkan_->InitObjects();
|
||||
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());
|
||||
*/
|
||||
}
|
||||
|
||||
void SwapInterval(int interval) override {
|
||||
}
|
||||
void *GetAPIContext() override {
|
||||
return vulkan_;
|
||||
}
|
||||
|
||||
Draw::DrawContext *GetDrawContext() override {
|
||||
return draw_;
|
||||
}
|
||||
private:
|
||||
Draw::DrawContext *draw_ = nullptr;
|
||||
VulkanContext *vulkan_ = nullptr;
|
||||
};
|
||||
|
||||
bool SDLVulkanGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, std::string *error_message) {
|
||||
window = SDL_CreateWindow("Initializing Vulkan...", x, y, pixel_xres, pixel_yres, mode);
|
||||
if (!window) {
|
||||
fprintf(stderr, "Error creating SDL window: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
init_glslang();
|
||||
|
||||
g_LogOptions.breakOnError = true;
|
||||
g_LogOptions.breakOnWarning = true;
|
||||
g_LogOptions.msgBoxOnError = false;
|
||||
|
||||
Version gitVer(PPSSPP_GIT_VERSION);
|
||||
|
||||
vulkan_ = new VulkanContext();
|
||||
if (vulkan_->InitError().size()) {
|
||||
*error_message = vulkan_->InitError();
|
||||
delete vulkan_;
|
||||
vulkan_ = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
int vulkanFlags = VULKAN_FLAG_PRESENT_MAILBOX;
|
||||
// vulkanFlags |= VULKAN_FLAG_VALIDATE;
|
||||
VulkanContext::CreateInfo info{};
|
||||
info.app_name = "PPSSPP";
|
||||
info.app_ver = gitVer.ToInteger();
|
||||
info.flags = vulkanFlags;
|
||||
if (VK_SUCCESS != vulkan_->CreateInstance(info)) {
|
||||
*error_message = vulkan_->InitError();
|
||||
delete vulkan_;
|
||||
vulkan_ = nullptr;
|
||||
return false;
|
||||
}
|
||||
vulkan_->ChooseDevice(vulkan_->GetBestPhysicalDevice());
|
||||
if (vulkan_->CreateDevice() != VK_SUCCESS) {
|
||||
*error_message = vulkan_->InitError();
|
||||
delete vulkan_;
|
||||
vulkan_ = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !defined(__APPLE__)
|
||||
SDL_SysWMinfo sys_info{};
|
||||
SDL_VERSION(&sys_info.version); //Set SDL version
|
||||
if (!SDL_GetWindowWMInfo(window, &sys_info)) {
|
||||
fprintf(stderr, "Error getting SDL window wm info: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
Display *display = sys_info.info.x11.display;
|
||||
Window x11_window = sys_info.info.x11.window;
|
||||
switch (sys_info.subsystem) {
|
||||
case SDL_SYSWM_X11:
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Vulkan subsystem %d not supported\n", sys_info.subsystem);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
// Fake to make it build on Apple. This code won't run there though.
|
||||
void *display = nullptr;
|
||||
int x11_window = 0;
|
||||
#endif
|
||||
ILOG("Display: %p", display);
|
||||
|
||||
#if defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
vulkan_->InitSurface(WINDOWSYSTEM_XLIB, (void*)display, (void *)(intptr_t)x11_window, pixel_xres, pixel_yres);
|
||||
#elif defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
vulkan_->InitSurface(WINDOWSYSTEM_XCB, (void*)XGetXCBConnection(display), (void *)(intptr_t)x11_window, pixel_xres, pixel_yres);
|
||||
#endif
|
||||
|
||||
if (!vulkan_->InitObjects()) {
|
||||
*error_message = vulkan_->InitError();
|
||||
Shutdown();
|
||||
return false;
|
||||
}
|
||||
|
||||
draw_ = Draw::T3DCreateVulkanContext(vulkan_, false);
|
||||
bool success = draw_->CreatePresets();
|
||||
assert(success);
|
||||
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SDLVulkanGraphicsContext::Shutdown() {
|
||||
if (draw_)
|
||||
draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vulkan_->GetBackbufferWidth(), vulkan_->GetBackbufferHeight());
|
||||
delete draw_;
|
||||
draw_ = nullptr;
|
||||
vulkan_->WaitUntilQueueIdle();
|
||||
vulkan_->DestroyObjects();
|
||||
vulkan_->DestroyDevice();
|
||||
vulkan_->DestroyDebugMsgCallback();
|
||||
vulkan_->DestroyInstance();
|
||||
delete vulkan_;
|
||||
vulkan_ = nullptr;
|
||||
finalize_glslang();
|
||||
}
|
||||
|
||||
int getDisplayNumber(void) {
|
||||
int displayNumber = 0;
|
||||
char * displayNumberStr;
|
||||
@@ -399,11 +671,11 @@ static float parseFloat(const char *str) {
|
||||
}
|
||||
}
|
||||
|
||||
void ToggleFullScreenIfFlagSet() {
|
||||
void ToggleFullScreenIfFlagSet(SDL_Window *window) {
|
||||
if (g_ToggleFullScreenNextFrame) {
|
||||
g_ToggleFullScreenNextFrame = false;
|
||||
|
||||
Uint32 window_flags = SDL_GetWindowFlags(g_Screen);
|
||||
Uint32 window_flags = SDL_GetWindowFlags(window);
|
||||
if (g_ToggleFullScreenType == -1) {
|
||||
window_flags ^= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
} else if (g_ToggleFullScreenType == 1) {
|
||||
@@ -411,7 +683,7 @@ void ToggleFullScreenIfFlagSet() {
|
||||
} else {
|
||||
window_flags &= ~SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
}
|
||||
SDL_SetWindowFullscreen(g_Screen, window_flags);
|
||||
SDL_SetWindowFullscreen(window, window_flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,57 +691,20 @@ void ToggleFullScreenIfFlagSet() {
|
||||
#undef main
|
||||
#endif
|
||||
int main(int argc, char *argv[]) {
|
||||
glslang::InitializeProcess();
|
||||
|
||||
#if PPSSPP_PLATFORM(RPI)
|
||||
bcm_host_init();
|
||||
#endif
|
||||
putenv((char*)"SDL_VIDEO_CENTERED=1");
|
||||
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
|
||||
|
||||
std::string app_name;
|
||||
std::string app_name_nice;
|
||||
std::string version;
|
||||
bool landscape;
|
||||
NativeGetAppInfo(&app_name, &app_name_nice, &landscape, &version);
|
||||
|
||||
bool joystick_enabled = true;
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_AUDIO) < 0) {
|
||||
joystick_enabled = false;
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
|
||||
fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
if (VulkanMayBeAvailable()) {
|
||||
printf("Vulkan might be available.\n");
|
||||
} else {
|
||||
printf("Vulkan is not available.\n");
|
||||
}
|
||||
|
||||
#ifdef USING_EGL
|
||||
if (EGL_Open())
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
// Get the video info before doing anything else, so we don't get skewed resolution results.
|
||||
// TODO: support multiple displays correctly
|
||||
SDL_DisplayMode displayMode;
|
||||
int should_be_zero = SDL_GetCurrentDisplayMode(0, &displayMode);
|
||||
if (should_be_zero != 0) {
|
||||
fprintf(stderr, "Could not get display mode: %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
g_DesktopWidth = displayMode.w;
|
||||
g_DesktopHeight = displayMode.h;
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
SDL_GL_SetSwapInterval(1);
|
||||
|
||||
Uint32 mode;
|
||||
#ifdef USING_GLES2
|
||||
mode = SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN;
|
||||
#else
|
||||
mode = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
|
||||
#endif
|
||||
int set_xres = -1;
|
||||
int set_yres = -1;
|
||||
bool portrait = false;
|
||||
@@ -481,6 +716,7 @@ int main(int argc, char *argv[]) {
|
||||
int remain_argc = 1;
|
||||
const char *remain_argv[256] = { argv[0] };
|
||||
|
||||
Uint32 mode = 0;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (!strcmp(argv[i],"--fullscreen"))
|
||||
mode |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
@@ -509,6 +745,47 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
std::string app_name;
|
||||
std::string app_name_nice;
|
||||
std::string version;
|
||||
bool landscape;
|
||||
NativeGetAppInfo(&app_name, &app_name_nice, &landscape, &version);
|
||||
|
||||
bool joystick_enabled = true;
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_AUDIO) < 0) {
|
||||
fprintf(stderr, "Failed to initialize SDL with joystick support. Retrying without.\n");
|
||||
joystick_enabled = false;
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
|
||||
fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: How do we get this into the GraphicsContext?
|
||||
#ifdef USING_EGL
|
||||
if (EGL_Open())
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
// Get the video info before doing anything else, so we don't get skewed resolution results.
|
||||
// TODO: support multiple displays correctly
|
||||
SDL_DisplayMode displayMode;
|
||||
int should_be_zero = SDL_GetCurrentDisplayMode(0, &displayMode);
|
||||
if (should_be_zero != 0) {
|
||||
fprintf(stderr, "Could not get display mode: %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
g_DesktopWidth = displayMode.w;
|
||||
g_DesktopHeight = displayMode.h;
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
SDL_GL_SetSwapInterval(1);
|
||||
|
||||
// Is resolution is too low to run windowed
|
||||
if (g_DesktopWidth < 480 * 2 && g_DesktopHeight < 272 * 2) {
|
||||
mode |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
@@ -552,12 +829,6 @@ int main(int argc, char *argv[]) {
|
||||
dp_xres = (float)pixel_xres * dpi_scale;
|
||||
dp_yres = (float)pixel_yres * dpi_scale;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// VFSRegister("temp/", new DirectoryAssetReader("E:\\Temp\\"));
|
||||
TCHAR path[MAX_PATH];
|
||||
SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, path);
|
||||
PathAppend(path, (app_name + "\\").c_str());
|
||||
#else
|
||||
// Mac / Linux
|
||||
char path[2048];
|
||||
const char *the_path = getenv("HOME");
|
||||
@@ -569,13 +840,8 @@ int main(int argc, char *argv[]) {
|
||||
strcpy(path, the_path);
|
||||
if (path[strlen(path)-1] != '/')
|
||||
strcat(path, "/");
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
NativeInit(remain_argc, (const char **)remain_argv, path, "D:\\", nullptr);
|
||||
#else
|
||||
NativeInit(remain_argc, (const char **)remain_argv, path, "/tmp", nullptr);
|
||||
#endif
|
||||
|
||||
// Use the setting from the config when initing the window.
|
||||
if (g_Config.bFullScreen)
|
||||
@@ -584,100 +850,6 @@ int main(int argc, char *argv[]) {
|
||||
int x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(getDisplayNumber());
|
||||
int y = SDL_WINDOWPOS_UNDEFINED;
|
||||
|
||||
struct GLVersionPair {
|
||||
int major;
|
||||
int minor;
|
||||
};
|
||||
GLVersionPair attemptVersions[] = {
|
||||
{4, 6}, {4, 5}, {4, 4}, {4, 3}, {4, 2}, {4, 1}, {4, 0},
|
||||
{3, 3}, {3, 2}, {3, 1}, {3, 0},
|
||||
};
|
||||
|
||||
SDL_GLContext glContext = nullptr;
|
||||
for (size_t i = 0; i < ARRAY_SIZE(attemptVersions); ++i) {
|
||||
const auto &ver = attemptVersions[i];
|
||||
// Make sure to request a somewhat modern GL context at least - the
|
||||
// latest supported by MacOS X (really, really sad...)
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, ver.major);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, ver.minor);
|
||||
SetGLCoreContext(true);
|
||||
|
||||
g_Screen = SDL_CreateWindow(app_name_nice.c_str(), x,y, pixel_xres, pixel_yres, mode);
|
||||
if (g_Screen == nullptr) {
|
||||
NativeShutdown();
|
||||
fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
return 2;
|
||||
}
|
||||
|
||||
glContext = SDL_GL_CreateContext(g_Screen);
|
||||
if (glContext != nullptr) {
|
||||
// Victory, got one.
|
||||
break;
|
||||
}
|
||||
|
||||
// Let's keep trying. To be safe, destroy the window - docs say needed to change profile.
|
||||
// in practice, it doesn't seem to matter, but maybe it differs by platform.
|
||||
SDL_DestroyWindow(g_Screen);
|
||||
}
|
||||
|
||||
if (glContext == nullptr) {
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
SetGLCoreContext(false);
|
||||
|
||||
g_Screen = SDL_CreateWindow(app_name_nice.c_str(), x,y, pixel_xres, pixel_yres, mode);
|
||||
if (g_Screen == nullptr) {
|
||||
NativeShutdown();
|
||||
fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
return 2;
|
||||
}
|
||||
|
||||
glContext = SDL_GL_CreateContext(g_Screen);
|
||||
if (glContext == nullptr) {
|
||||
NativeShutdown();
|
||||
fprintf(stderr, "SDL_GL_CreateContext failed: %s\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USING_EGL
|
||||
EGL_Init();
|
||||
#endif
|
||||
|
||||
SDL_SetWindowTitle(g_Screen, (app_name_nice + " " + PPSSPP_GIT_VERSION).c_str());
|
||||
|
||||
#ifdef MOBILE_DEVICE
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef USING_GLES2
|
||||
// Some core profile drivers elide certain extensions from GL_EXTENSIONS/etc.
|
||||
// glewExperimental allows us to force GLEW to search for the pointers anyway.
|
||||
if (gl_extensions.IsCoreContext)
|
||||
glewExperimental = true;
|
||||
if (GLEW_OK != glewInit()) {
|
||||
printf("Failed to initialize glew!\n");
|
||||
return 1;
|
||||
}
|
||||
// Unfortunately, glew will generate an invalid enum error, ignore.
|
||||
if (gl_extensions.IsCoreContext)
|
||||
glGetError();
|
||||
|
||||
if (GLEW_VERSION_2_0) {
|
||||
printf("OpenGL 2.0 or higher.\n");
|
||||
} else {
|
||||
printf("Sorry, this program requires OpenGL 2.0.\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
pixel_in_dps_x = (float)pixel_xres / dp_xres;
|
||||
pixel_in_dps_y = (float)pixel_yres / dp_yres;
|
||||
g_dpi_scale_x = dp_xres / (float)pixel_xres;
|
||||
@@ -688,9 +860,35 @@ int main(int argc, char *argv[]) {
|
||||
printf("Pixels: %i x %i\n", pixel_xres, pixel_yres);
|
||||
printf("Virtual pixels: %i x %i\n", dp_xres, dp_yres);
|
||||
|
||||
glslang::InitializeProcess();
|
||||
GraphicsContext *graphicsContext = nullptr;
|
||||
SDL_Window *window = nullptr;
|
||||
std::string error_message;
|
||||
if (g_Config.iGPUBackend == GPU_BACKEND_OPENGL) {
|
||||
SDLGLGraphicsContext *ctx = new SDLGLGraphicsContext();
|
||||
if (ctx->Init(window, x, y, mode, &error_message) != 0) {
|
||||
printf("GL init error '%s'\n", error_message.c_str());
|
||||
}
|
||||
graphicsContext = ctx;
|
||||
} else if (g_Config.iGPUBackend == GPU_BACKEND_VULKAN) {
|
||||
SDLVulkanGraphicsContext *ctx = new SDLVulkanGraphicsContext();
|
||||
if (!ctx->Init(window, x, y, mode, &error_message)) {
|
||||
printf("Vulkan init error '%s' - falling back to GL\n", error_message.c_str());
|
||||
g_Config.iGPUBackend = GPU_BACKEND_OPENGL;
|
||||
delete ctx;
|
||||
SDLGLGraphicsContext *glctx = new SDLGLGraphicsContext();
|
||||
glctx->Init(window, x, y, mode, &error_message);
|
||||
graphicsContext = glctx;
|
||||
} else {
|
||||
graphicsContext = ctx;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_SetWindowTitle(window, (app_name_nice + " " + PPSSPP_GIT_VERSION).c_str());
|
||||
|
||||
#ifdef MOBILE_DEVICE
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
#endif
|
||||
|
||||
GraphicsContext *graphicsContext = new GLDummyGraphicsContext();
|
||||
NativeInitGraphics(graphicsContext);
|
||||
|
||||
NativeResized();
|
||||
@@ -721,18 +919,14 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
// Audio must be unpaused _after_ NativeInit()
|
||||
SDL_PauseAudio(0);
|
||||
#ifndef _WIN32
|
||||
if (joystick_enabled) {
|
||||
joystick = new SDLJoystick();
|
||||
} else {
|
||||
joystick = nullptr;
|
||||
}
|
||||
#endif
|
||||
EnableFZ();
|
||||
|
||||
int framecount = 0;
|
||||
float t = 0;
|
||||
float lastT = 0;
|
||||
bool mouseDown = false;
|
||||
|
||||
while (true) {
|
||||
@@ -751,7 +945,7 @@ int main(int argc, char *argv[]) {
|
||||
switch (event.window.event) {
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
{
|
||||
Uint32 window_flags = SDL_GetWindowFlags(g_Screen);
|
||||
Uint32 window_flags = SDL_GetWindowFlags(window);
|
||||
bool fullscreen = (window_flags & SDL_WINDOW_FULLSCREEN);
|
||||
|
||||
pixel_xres = event.window.data1;
|
||||
@@ -893,11 +1087,9 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
#ifndef _WIN32
|
||||
if (joystick) {
|
||||
joystick->ProcessInput(event);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -921,44 +1113,25 @@ int main(int argc, char *argv[]) {
|
||||
// glsl_refresh(); // auto-reloads modified GLSL shaders once per second.
|
||||
}
|
||||
|
||||
#ifdef USING_EGL
|
||||
eglSwapBuffers(g_eglDisplay, g_eglSurface);
|
||||
#else
|
||||
if (!keys[SDLK_TAB] || t - lastT >= 1.0/60.0) {
|
||||
SDL_GL_SwapWindow(g_Screen);
|
||||
lastT = t;
|
||||
}
|
||||
#endif
|
||||
graphicsContext->SwapBuffers();
|
||||
|
||||
ToggleFullScreenIfFlagSet();
|
||||
ToggleFullScreenIfFlagSet(window);
|
||||
time_update();
|
||||
t = time_now();
|
||||
framecount++;
|
||||
}
|
||||
#ifndef _WIN32
|
||||
delete joystick;
|
||||
#endif
|
||||
NativeShutdownGraphics();
|
||||
graphicsContext->Shutdown();
|
||||
NativeShutdown();
|
||||
delete graphicsContext;
|
||||
glslang::FinalizeProcess();
|
||||
// Faster exit, thanks to the OS. Remove this if you want to debug shutdown
|
||||
// The speed difference is only really noticable on Linux. On Windows you do notice it though
|
||||
#ifndef MOBILE_DEVICE
|
||||
exit(0);
|
||||
#endif
|
||||
|
||||
SDL_PauseAudio(1);
|
||||
SDL_CloseAudio();
|
||||
#ifdef USING_EGL
|
||||
EGL_Close();
|
||||
#endif
|
||||
SDL_GL_DeleteContext(glContext);
|
||||
SDL_Quit();
|
||||
#if PPSSPP_PLATFORM(RPI)
|
||||
bcm_host_deinit();
|
||||
#endif
|
||||
|
||||
exit(0);
|
||||
glslang::FinalizeProcess();
|
||||
return 0;
|
||||
}
|
||||
@@ -48,7 +48,6 @@
|
||||
#include "Common/KeyMap.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/OSVersion.h"
|
||||
#include "Common/Vulkan/VulkanLoader.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/Host.h"
|
||||
#include "Core/System.h"
|
||||
@@ -73,6 +72,8 @@ extern bool iosCanUseJit;
|
||||
extern bool targetIsJailbroken;
|
||||
#endif
|
||||
|
||||
extern bool VulkanMayBeAvailable();
|
||||
|
||||
GameSettingsScreen::GameSettingsScreen(std::string gamePath, std::string gameID, bool editThenRestore)
|
||||
: UIDialogScreenWithGameBackground(gamePath), gameID_(gameID), enableReports_(false), editThenRestore_(editThenRestore) {
|
||||
lastVertical_ = UseVerticalLayout();
|
||||
@@ -191,7 +192,7 @@ void GameSettingsScreen::CreateViews() {
|
||||
}
|
||||
#endif
|
||||
bool vulkanAvailable = false;
|
||||
#if PPSSPP_PLATFORM(WINDOWS) || PPSSPP_PLATFORM(ANDROID)
|
||||
#ifndef IOS
|
||||
vulkanAvailable = VulkanMayBeAvailable();
|
||||
#endif
|
||||
if (!vulkanAvailable) {
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#include "base/timeutil.h"
|
||||
#include "ext/vjson/json.h"
|
||||
|
||||
+24
-58
@@ -1,4 +1,6 @@
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
#include "base/timeutil.h"
|
||||
#include "base/NativeApp.h"
|
||||
@@ -21,20 +23,13 @@
|
||||
#include "Core/Config.h"
|
||||
#include "thread/threadutil.h"
|
||||
|
||||
#include <tchar.h>
|
||||
#include <process.h>
|
||||
#include <intrin.h>
|
||||
|
||||
#pragma intrinsic(_InterlockedExchange)
|
||||
|
||||
static std::mutex emuThreadLock;
|
||||
static HANDLE emuThread;
|
||||
static volatile long emuThreadReady;
|
||||
static std::thread emuThread;
|
||||
static std::atomic<int> emuThreadState;
|
||||
|
||||
extern std::vector<std::wstring> GetWideCmdLine();
|
||||
|
||||
enum EmuThreadStatus : long
|
||||
{
|
||||
enum EmuThreadStatus : int {
|
||||
THREAD_NONE = 0,
|
||||
THREAD_INIT,
|
||||
THREAD_CORE_LOOP,
|
||||
@@ -42,75 +37,51 @@ enum EmuThreadStatus : long
|
||||
THREAD_END,
|
||||
};
|
||||
|
||||
HANDLE EmuThread_GetThreadHandle()
|
||||
{
|
||||
void EmuThreadFunc();
|
||||
|
||||
void EmuThread_Start() {
|
||||
std::lock_guard<std::mutex> guard(emuThreadLock);
|
||||
return emuThread;
|
||||
emuThread = std::thread(&EmuThreadFunc);
|
||||
}
|
||||
|
||||
unsigned int WINAPI TheThread(void *);
|
||||
|
||||
void EmuThread_Start()
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(emuThreadLock);
|
||||
emuThread = (HANDLE)_beginthreadex(0, 0, &TheThread, 0, 0, 0);
|
||||
}
|
||||
|
||||
void EmuThread_Stop()
|
||||
{
|
||||
void EmuThread_Stop() {
|
||||
// Already stopped?
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(emuThreadLock);
|
||||
if (emuThread == NULL || emuThreadReady == THREAD_END)
|
||||
if (emuThreadState == THREAD_END)
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateUIState(UISTATE_EXIT);
|
||||
Core_Stop();
|
||||
Core_WaitInactive(800);
|
||||
if (WAIT_TIMEOUT == WaitForSingleObject(emuThread, 800))
|
||||
{
|
||||
//_dbg_assert_msg_(COMMON, false, "Wait for EmuThread timed out.");
|
||||
}
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(emuThreadLock);
|
||||
CloseHandle(emuThread);
|
||||
emuThread = 0;
|
||||
}
|
||||
emuThread.join();
|
||||
|
||||
PostMessage(MainWindow::GetHWND(), MainWindow::WM_USER_UPDATE_UI, 0, 0);
|
||||
}
|
||||
|
||||
bool EmuThread_Ready()
|
||||
{
|
||||
return emuThreadReady == THREAD_CORE_LOOP;
|
||||
bool EmuThread_Ready() {
|
||||
return emuThreadState == THREAD_CORE_LOOP;
|
||||
}
|
||||
|
||||
unsigned int WINAPI TheThread(void *)
|
||||
{
|
||||
_InterlockedExchange(&emuThreadReady, THREAD_INIT);
|
||||
void EmuThreadFunc() {
|
||||
emuThreadState = THREAD_INIT;
|
||||
|
||||
setCurrentThreadName("Emu"); // And graphics...
|
||||
setCurrentThreadName("Emu");
|
||||
|
||||
host = new WindowsHost(MainWindow::GetHInstance(), MainWindow::GetHWND(), MainWindow::GetDisplayHWND());
|
||||
host->SetWindowTitle(nullptr);
|
||||
|
||||
// Convert the command-line arguments to Unicode, then to proper UTF-8
|
||||
// (the benefit being that we don't have to pollute the UI project with win32 ifdefs and lots of Convert<whatever>To<whatever>).
|
||||
// This avoids issues with PPSSPP inadvertently destroying paths with Unicode glyphs
|
||||
// (using the ANSI args resulted in Japanese/Chinese glyphs being turned into question marks, at least for me..).
|
||||
// -TheDax
|
||||
// We convert command line arguments to UTF-8 immediately.
|
||||
std::vector<std::wstring> wideArgs = GetWideCmdLine();
|
||||
std::vector<std::string> argsUTF8;
|
||||
for (auto& string : wideArgs) {
|
||||
argsUTF8.push_back(ConvertWStringToUTF8(string));
|
||||
}
|
||||
|
||||
std::vector<const char *> args;
|
||||
|
||||
for (auto& string : argsUTF8) {
|
||||
args.push_back(string.c_str());
|
||||
}
|
||||
|
||||
bool performingRestart = NativeIsRestarting();
|
||||
NativeInit(static_cast<int>(args.size()), &args[0], "1234", "1234", nullptr);
|
||||
|
||||
@@ -165,7 +136,7 @@ unsigned int WINAPI TheThread(void *)
|
||||
}
|
||||
|
||||
// No safe way out without graphics.
|
||||
ExitProcess(1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
NativeInitGraphics(graphicsContext);
|
||||
@@ -179,34 +150,29 @@ unsigned int WINAPI TheThread(void *)
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
_InterlockedExchange(&emuThreadReady, THREAD_CORE_LOOP);
|
||||
emuThreadState = THREAD_CORE_LOOP;
|
||||
|
||||
if (g_Config.bBrowse)
|
||||
PostMessage(MainWindow::GetHWND(), WM_COMMAND, ID_FILE_LOAD, 0);
|
||||
|
||||
Core_EnableStepping(FALSE);
|
||||
|
||||
while (GetUIState() != UISTATE_EXIT)
|
||||
{
|
||||
while (GetUIState() != UISTATE_EXIT) {
|
||||
// We're here again, so the game quit. Restart Core_Run() which controls the UI.
|
||||
// This way they can load a new game.
|
||||
if (!Core_IsActive())
|
||||
UpdateUIState(UISTATE_MENU);
|
||||
|
||||
Core_Run(graphicsContext);
|
||||
}
|
||||
|
||||
shutdown:
|
||||
_InterlockedExchange(&emuThreadReady, THREAD_SHUTDOWN);
|
||||
emuThreadState = THREAD_SHUTDOWN;
|
||||
|
||||
NativeShutdownGraphics();
|
||||
|
||||
// NativeShutdown deletes the graphics context through host->ShutdownGraphics().
|
||||
NativeShutdown();
|
||||
|
||||
_InterlockedExchange(&emuThreadReady, THREAD_END);
|
||||
|
||||
return 0;
|
||||
emuThreadState = THREAD_END;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 @@ public:
|
||||
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();
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#include "input/input_state.h"
|
||||
#include "thread/threadutil.h"
|
||||
|
||||
@@ -284,13 +284,17 @@ bool AndroidVulkanContext::Init(ANativeWindow *wnd, int desiredBackbufferSizeX,
|
||||
g_LogOptions.breakOnWarning = true;
|
||||
g_LogOptions.msgBoxOnError = false;
|
||||
|
||||
ILOG("Creating vulkan context");
|
||||
ILOG("Creating Vulkan context");
|
||||
Version gitVer(PPSSPP_GIT_VERSION);
|
||||
|
||||
if (!g_Vulkan) {
|
||||
g_Vulkan = new VulkanContext();
|
||||
}
|
||||
if (VK_SUCCESS != g_Vulkan->CreateInstance("PPSSPP", gitVer.ToInteger(), VULKAN_FLAG_PRESENT_MAILBOX | VULKAN_FLAG_PRESENT_FIFO_RELAXED)) {
|
||||
VulkanContext::CreateInfo info{};
|
||||
info.app_name = "PPSSPP";
|
||||
info.app_ver = gitVer.ToInteger();
|
||||
info.flags = VULKAN_FLAG_PRESENT_MAILBOX | VULKAN_FLAG_PRESENT_FIFO_RELAXED;
|
||||
if (VK_SUCCESS != g_Vulkan->CreateInstance(info)) {
|
||||
ELOG("Failed to create vulkan context: %s", g_Vulkan->InitError().c_str());
|
||||
System_SendMessage("toast", "No Vulkan compatible device found. Using OpenGL instead.");
|
||||
delete g_Vulkan;
|
||||
@@ -310,7 +314,7 @@ bool AndroidVulkanContext::Init(ANativeWindow *wnd, int desiredBackbufferSizeX,
|
||||
g_Vulkan->ChooseDevice(physicalDevice);
|
||||
// Here we can enable device extensions if we like.
|
||||
|
||||
ILOG("Creating vulkan device");
|
||||
ILOG("Creating Vulkan device");
|
||||
if (g_Vulkan->CreateDevice() != VK_SUCCESS) {
|
||||
ILOG("Failed to create vulkan device: %s", g_Vulkan->InitError().c_str());
|
||||
System_SendMessage("toast", "No Vulkan driver found. Using OpenGL instead.");
|
||||
@@ -326,7 +330,7 @@ bool AndroidVulkanContext::Init(ANativeWindow *wnd, int desiredBackbufferSizeX,
|
||||
height = pixel_yres;
|
||||
}
|
||||
ILOG("InitSurfaceAndroid: width=%d height=%d", width, height);
|
||||
g_Vulkan->InitSurfaceAndroid(wnd, width, height);
|
||||
g_Vulkan->InitSurface(WINDOWSYSTEM_ANDROID, (void *)wnd, nullptr, width, height);
|
||||
if (g_validate_) {
|
||||
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);
|
||||
@@ -386,7 +390,7 @@ void AndroidVulkanContext::Resize() {
|
||||
g_Vulkan->DestroyObjects();
|
||||
|
||||
// backbufferResize updated these values. TODO: Notify another way?
|
||||
g_Vulkan->ReinitSurfaceAndroid(pixel_xres, pixel_yres);
|
||||
g_Vulkan->ReinitSurface(pixel_xres, pixel_yres);
|
||||
g_Vulkan->InitObjects();
|
||||
draw_->HandleEvent(Draw::Event::GOT_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
|
||||
ILOG("AndroidVulkanContext::Resize end (%d, %d)", g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight());
|
||||
|
||||
+1
-1
Submodule assets/lang updated: 6537fc1bf3...1e3e4a0ba0.
@@ -111,7 +111,7 @@ void NativeSaveState(); // onDestroy
|
||||
void NativePermissionStatus(SystemPermission permission, PermissionStatus status);
|
||||
|
||||
// Calls back into Java / SDL
|
||||
// These APIs must be implemented by every port (for example app-android.cpp, PCMain.cpp).
|
||||
// These APIs must be implemented by every port (for example app-android.cpp, SDLMain.cpp).
|
||||
// You are free to call these.
|
||||
void SystemToast(const char *text);
|
||||
void ShowKeyboard();
|
||||
|
||||
@@ -299,13 +299,13 @@
|
||||
<ClCompile Include="base\colorutil.cpp" />
|
||||
<ClCompile Include="base\display.cpp" />
|
||||
<ClCompile Include="base\logging.cpp" />
|
||||
<ClCompile Include="base\PCMain.cpp">
|
||||
<ClCompile Include="..\..\SDL\SDLMain.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="base\QtMain.cpp">
|
||||
<ClCompile Include="..\..\Qt\QtMain.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
@@ -761,4 +761,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -739,10 +739,10 @@
|
||||
<ClCompile Include="thread\executor.cpp">
|
||||
<Filter>thread</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="base\PCMain.cpp">
|
||||
<ClCompile Include="..\..\SDL\SDLMain.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="base\QtMain.cpp">
|
||||
<ClCompile Include="..\..\Qt\QtMain.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="file\free.cpp">
|
||||
@@ -868,4 +868,4 @@
|
||||
<UniqueIdentifier>{06c6305a-a646-485b-85b9-645a24dd6553}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace Draw {
|
||||
|
||||
|
||||
@@ -78,8 +78,6 @@ void VulkanQueueRunner::DestroyDeviceObjects() {
|
||||
}
|
||||
|
||||
void VulkanQueueRunner::InitBackbufferRenderPass() {
|
||||
VkResult U_ASSERT_ONLY res;
|
||||
|
||||
VkAttachmentDescription attachments[2];
|
||||
attachments[0].format = vulkan_->GetSwapchainFormat();
|
||||
attachments[0].samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
@@ -139,7 +137,7 @@ void VulkanQueueRunner::InitBackbufferRenderPass() {
|
||||
rp_info.dependencyCount = 1;
|
||||
rp_info.pDependencies = &dep;
|
||||
|
||||
res = vkCreateRenderPass(vulkan_->GetDevice(), &rp_info, nullptr, &backbufferRenderPass_);
|
||||
VkResult res = vkCreateRenderPass(vulkan_->GetDevice(), &rp_info, nullptr, &backbufferRenderPass_);
|
||||
assert(res == VK_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "thread/threadutil.h"
|
||||
|
||||
@@ -1,35 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
// Note that name must be a global string that lives until the end of the process,
|
||||
// for assertThreadName to work.
|
||||
void setCurrentThreadName(const char *threadName);
|
||||
void AssertCurrentThreadName(const char *threadName);
|
||||
|
||||
class event {
|
||||
public:
|
||||
void notify_one() {
|
||||
cond_.notify_one();
|
||||
}
|
||||
|
||||
// notify_all is not really possible to implement with win32 events?
|
||||
|
||||
void wait(std::mutex &mtx) {
|
||||
// broken logic
|
||||
std::unique_lock<std::mutex> guard(mtx);
|
||||
cond_.wait(guard);
|
||||
}
|
||||
|
||||
void wait_for(std::mutex &mtx, int milliseconds) {
|
||||
std::unique_lock<std::mutex> guard(mtx);
|
||||
cond_.wait_for(guard, std::chrono::milliseconds(milliseconds));
|
||||
}
|
||||
|
||||
void reset() {
|
||||
}
|
||||
private:
|
||||
std::condition_variable cond_;
|
||||
};
|
||||
void AssertCurrentThreadName(const char *threadName);
|
||||
Reference in new issue
Block a user