Merge pull request #19 from camdenorrb/force-60-plus-fps

Force 60 plus fps
This commit is contained in:
Camden 2024-12-22 23:18:43 -06:00 committed by GitHub
commit e01a63c7e9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 218 additions and 153 deletions

View file

@ -21,9 +21,11 @@ endif()
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
target_sources(dolphin-nogui PRIVATE PlatformFBDev.cpp) target_sources(dolphin-nogui PRIVATE PlatformFBDev.cpp)
target_sources(dolphin-nogui PRIVATE PlatformDRM.cpp)
endif() endif()
if(ENABLE_DRM)
target_sources(dolphin-nogui PRIVATE PlatformDRM.cpp)
endif()
set_target_properties(dolphin-nogui PROPERTIES OUTPUT_NAME dolphin-emu-nogui) set_target_properties(dolphin-nogui PROPERTIES OUTPUT_NAME dolphin-emu-nogui)

View file

@ -221,7 +221,8 @@ int main(int argc, char* argv[])
"fbdev" "fbdev"
#endif #endif
#if HAVE_DRM #if HAVE_DRM
,"drm" ,
"drm"
#endif #endif
#if HAVE_X11 #if HAVE_X11
, ,

View file

@ -29,7 +29,6 @@ public:
WindowSystemInfo GetWindowSystemInfo() const override; WindowSystemInfo GetWindowSystemInfo() const override;
}; };
void PlatformDRM::SetTitle(const std::string& string) void PlatformDRM::SetTitle(const std::string& string)
{ {
std::fprintf(stdout, "%s\n", string.c_str()); std::fprintf(stdout, "%s\n", string.c_str());

View file

@ -36,16 +36,29 @@ SwapChain::~SwapChain()
DestroySurface(); DestroySurface();
} }
VkSurfaceKHR SwapChain::CreateVulkanSurface(VkInstance instance, VkPhysicalDevice physical_device, const WindowSystemInfo& wsi) // Custom comparator to sort by resolution
bool CompareResolutions(const VkDisplayModePropertiesKHR& a, const VkDisplayModePropertiesKHR& b)
{ {
const auto& params_a = a.parameters.visibleRegion;
const auto& params_b = b.parameters.visibleRegion;
if (params_a.width != params_b.width)
return params_a.width < params_b.width; // Sort by width first
return params_a.height < params_b.height; // Then by height
}
VkSurfaceKHR SwapChain::CreateVulkanSurface(VkInstance instance, VkPhysicalDevice physical_device,
const WindowSystemInfo& wsi)
{
#if defined(VK_USE_PLATFORM_DISPLAY_KHR) #if defined(VK_USE_PLATFORM_DISPLAY_KHR)
if (wsi.type == WindowSystemType::DRM) if (wsi.type == WindowSystemType::DRM)
{ {
// Get the first display // Get the first display
uint32_t display_count = 1; uint32_t display_count = 1;
VkDisplayPropertiesKHR display_props; VkDisplayPropertiesKHR display_props;
if (VkResult err = vkGetPhysicalDeviceDisplayPropertiesKHR(physical_device, &display_count, &display_props); err != VK_SUCCESS && err != VK_INCOMPLETE) if (VkResult err = vkGetPhysicalDeviceDisplayPropertiesKHR(physical_device, &display_count,
&display_props);
err != VK_SUCCESS && err != VK_INCOMPLETE)
{ {
LOG_VULKAN_ERROR(err, "vkGetPhysicalDeviceDisplayPropertiesKHR failed: "); LOG_VULKAN_ERROR(err, "vkGetPhysicalDeviceDisplayPropertiesKHR failed: ");
return VK_NULL_HANDLE; return VK_NULL_HANDLE;
@ -53,7 +66,9 @@ if (wsi.type == WindowSystemType::DRM)
// Get the first mode of the display // Get the first mode of the display
uint32_t mode_count = 0; uint32_t mode_count = 0;
if (VkResult err = vkGetDisplayModePropertiesKHR(physical_device, display_props.display, &mode_count, nullptr); err != VK_SUCCESS) if (VkResult err = vkGetDisplayModePropertiesKHR(physical_device, display_props.display,
&mode_count, nullptr);
err != VK_SUCCESS)
{ {
LOG_VULKAN_ERROR(err, "vkGetDisplayModePropertiesKHR failed: "); LOG_VULKAN_ERROR(err, "vkGetDisplayModePropertiesKHR failed: ");
return VK_NULL_HANDLE; return VK_NULL_HANDLE;
@ -65,17 +80,56 @@ if (wsi.type == WindowSystemType::DRM)
return VK_NULL_HANDLE; return VK_NULL_HANDLE;
} }
VkDisplayModePropertiesKHR mode_props; auto* all_mode_props = static_cast<VkDisplayModePropertiesKHR*>(calloc(mode_count, sizeof(VkDisplayModePropertiesKHR)));
mode_count = 1; if (VkResult err = vkGetDisplayModePropertiesKHR(physical_device, display_props.display,
if (VkResult err = vkGetDisplayModePropertiesKHR(physical_device, display_props.display, &mode_count, &mode_props); err != VK_SUCCESS && err != VK_INCOMPLETE) &mode_count, all_mode_props);
err != VK_SUCCESS && err != VK_INCOMPLETE)
{ {
LOG_VULKAN_ERROR(err, "vkGetDisplayModePropertiesKHR failed: "); LOG_VULKAN_ERROR(err, "vkGetDisplayModePropertiesKHR failed: ");
return VK_NULL_HANDLE; return VK_NULL_HANDLE;
} }
// Sort and display modes
std::vector all_mode_props_vector(all_mode_props, all_mode_props + mode_count);
std::ranges::sort(all_mode_props_vector, CompareResolutions);
for (int i = 0; i < mode_count; ++i)
{
const VkDisplayModeParametersKHR* params = &all_mode_props_vector[i].parameters;
printf("Mode %d: %d x %d (%.2f fps)\n", i,
params->visibleRegion.width, params->visibleRegion.height,
static_cast<float>(params->refreshRate) / 1000.0f);
}
for (int i = 0; i < mode_count; ++i)
{
VkDisplayModeParametersKHR *params = &all_mode_props[i].parameters;
printf("Mode %d: %d x %d (%.2f fps)\n", i,
params->visibleRegion.width, params->visibleRegion.height,
static_cast<float>(params->refreshRate) / 1000.0f);
}
int selected_mode = -1;
do
{
printf("Please select a mode (0 to %d): ", mode_count - 1);
if (scanf("%d", &selected_mode) != 1) {
// Clear invalid input
while (getchar() != '\n');
printf("Invalid input. Please enter a number.\n");
selected_mode = -1;
} else if (selected_mode < 0 || selected_mode >= mode_count) {
printf("Invalid selection. Please choose a valid mode.\n");
}
} while (selected_mode < 0 || selected_mode >= mode_count);
VkDisplayModePropertiesKHR mode_props = all_mode_props[selected_mode];
// Get the list of planes // Get the list of planes
uint32_t plane_count = 0; uint32_t plane_count = 0;
if (VkResult err = vkGetPhysicalDeviceDisplayPlanePropertiesKHR(physical_device, &plane_count, nullptr); err != VK_SUCCESS) if (VkResult err =
vkGetPhysicalDeviceDisplayPlanePropertiesKHR(physical_device, &plane_count, nullptr);
err != VK_SUCCESS)
{ {
LOG_VULKAN_ERROR(err, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR failed: "); LOG_VULKAN_ERROR(err, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR failed: ");
return VK_NULL_HANDLE; return VK_NULL_HANDLE;
@ -95,7 +149,8 @@ if (wsi.type == WindowSystemType::DRM)
{ {
// Query the number of displays supported by the plane // Query the number of displays supported by the plane
display_count = 0; display_count = 0;
VkResult err = vkGetDisplayPlaneSupportedDisplaysKHR(physical_device, plane_index, &display_count, nullptr); VkResult err = vkGetDisplayPlaneSupportedDisplaysKHR(physical_device, plane_index,
&display_count, nullptr);
if (err != VK_SUCCESS) if (err != VK_SUCCESS)
{ {
LOG_VULKAN_ERROR(err, "vkGetDisplayPlaneSupportedDisplaysKHR (count query) failed: "); LOG_VULKAN_ERROR(err, "vkGetDisplayPlaneSupportedDisplaysKHR (count query) failed: ");
@ -107,7 +162,8 @@ if (wsi.type == WindowSystemType::DRM)
// Allocate memory to hold the supported displays // Allocate memory to hold the supported displays
std::vector<VkDisplayKHR> displays(display_count); std::vector<VkDisplayKHR> displays(display_count);
err = vkGetDisplayPlaneSupportedDisplaysKHR(physical_device, plane_index, &display_count, displays.data()); err = vkGetDisplayPlaneSupportedDisplaysKHR(physical_device, plane_index, &display_count,
displays.data());
if (err != VK_SUCCESS) if (err != VK_SUCCESS)
{ {
LOG_VULKAN_ERROR(err, "vkGetDisplayPlaneSupportedDisplaysKHR (fetch displays) failed: "); LOG_VULKAN_ERROR(err, "vkGetDisplayPlaneSupportedDisplaysKHR (fetch displays) failed: ");
@ -134,7 +190,6 @@ if (wsi.type == WindowSystemType::DRM)
return VK_NULL_HANDLE; return VK_NULL_HANDLE;
} }
if (compatible_plane_index == UINT32_MAX) if (compatible_plane_index == UINT32_MAX)
{ {
ERROR_LOG_FMT(VIDEO, "No compatible plane found for the display!"); ERROR_LOG_FMT(VIDEO, "No compatible plane found for the display!");
@ -143,7 +198,9 @@ if (wsi.type == WindowSystemType::DRM)
// Get capabilities of the compatible plane // Get capabilities of the compatible plane
VkDisplayPlaneCapabilitiesKHR plane_capabilities; VkDisplayPlaneCapabilitiesKHR plane_capabilities;
if (VkResult err = vkGetDisplayPlaneCapabilitiesKHR(physical_device, mode_props.displayMode, compatible_plane_index, &plane_capabilities); err != VK_SUCCESS) if (VkResult err = vkGetDisplayPlaneCapabilitiesKHR(
physical_device, mode_props.displayMode, compatible_plane_index, &plane_capabilities);
err != VK_SUCCESS)
{ {
LOG_VULKAN_ERROR(err, "vkGetDisplayPlaneCapabilitiesKHR failed: "); LOG_VULKAN_ERROR(err, "vkGetDisplayPlaneCapabilitiesKHR failed: ");
return VK_NULL_HANDLE; return VK_NULL_HANDLE;
@ -176,11 +233,13 @@ if (wsi.type == WindowSystemType::DRM)
surface_create_info.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; surface_create_info.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
surface_create_info.globalAlpha = 1.0f; surface_create_info.globalAlpha = 1.0f;
surface_create_info.alphaMode = alpha_mode; surface_create_info.alphaMode = alpha_mode;
surface_create_info.imageExtent.width = display_props.physicalResolution.width; surface_create_info.imageExtent.width = mode_props.parameters.visibleRegion.width;
surface_create_info.imageExtent.height = display_props.physicalResolution.height; surface_create_info.imageExtent.height = mode_props.parameters.visibleRegion.height;
VkSurfaceKHR surface; VkSurfaceKHR surface;
if (VkResult res = vkCreateDisplayPlaneSurfaceKHR(instance, &surface_create_info, nullptr, &surface); res != VK_SUCCESS) if (VkResult res =
vkCreateDisplayPlaneSurfaceKHR(instance, &surface_create_info, nullptr, &surface);
res != VK_SUCCESS)
{ {
LOG_VULKAN_ERROR(res, "vkCreateDisplayPlaneSurfaceKHR failed: "); LOG_VULKAN_ERROR(res, "vkCreateDisplayPlaneSurfaceKHR failed: ");
return VK_NULL_HANDLE; return VK_NULL_HANDLE;
@ -329,20 +388,18 @@ bool SwapChain::SelectSurfaceFormat()
// because we already apply gamma ourselves, and we might not use sRGB gamma. // because we already apply gamma ourselves, and we might not use sRGB gamma.
// Force using a linear format instead, if this is the case. // Force using a linear format instead, if this is the case.
VkFormat format = VKTexture::GetLinearFormat(surface_format.format); VkFormat format = VKTexture::GetLinearFormat(surface_format.format);
if (surface_format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
{
if (format == VK_FORMAT_R8G8B8A8_UNORM) if (format == VK_FORMAT_R8G8B8A8_UNORM)
surface_format_RGBA8 = &surface_format; surface_format_RGBA8 = &surface_format;
else if (format == VK_FORMAT_B8G8R8A8_UNORM) else if (format == VK_FORMAT_B8G8R8A8_UNORM)
surface_format_BGRA8 = &surface_format; surface_format_BGRA8 = &surface_format;
else if (format == VK_FORMAT_A2B10G10R10_UNORM_PACK32) else if (format == VK_FORMAT_A2B10G10R10_UNORM_PACK32 &&
surface_format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
surface_format_RGB10_A2 = &surface_format; surface_format_RGB10_A2 = &surface_format;
}
else if (format == VK_FORMAT_R16G16B16A16_SFLOAT && else if (format == VK_FORMAT_R16G16B16A16_SFLOAT &&
surface_format.colorSpace == VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT) surface_format.colorSpace == VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT)
{
surface_format_RGBA16F_scRGB = &surface_format; surface_format_RGBA16F_scRGB = &surface_format;
} else
continue;
} }
const VkSurfaceFormatKHR* surface_format = nullptr; const VkSurfaceFormatKHR* surface_format = nullptr;
@ -738,7 +795,8 @@ bool SwapChain::RecreateSurface(void* native_handle)
// Re-create the surface with the new native handle // Re-create the surface with the new native handle
m_wsi.render_surface = native_handle; m_wsi.render_surface = native_handle;
m_surface = CreateVulkanSurface(g_vulkan_context->GetVulkanInstance(), g_vulkan_context->GetPhysicalDevice(), m_wsi); m_surface = CreateVulkanSurface(g_vulkan_context->GetVulkanInstance(),
g_vulkan_context->GetPhysicalDevice(), m_wsi);
if (m_surface == VK_NULL_HANDLE) if (m_surface == VK_NULL_HANDLE)
return false; return false;

View file

@ -25,7 +25,8 @@ public:
~SwapChain(); ~SwapChain();
// Creates a vulkan-renderable surface for the specified window handle. // Creates a vulkan-renderable surface for the specified window handle.
static VkSurfaceKHR CreateVulkanSurface(VkInstance instance, VkPhysicalDevice physical_device, const WindowSystemInfo &wsi); static VkSurfaceKHR CreateVulkanSurface(VkInstance instance, VkPhysicalDevice physical_device,
const WindowSystemInfo& wsi);
// Create a new swap chain from a pre-existing surface. // Create a new swap chain from a pre-existing surface.
static std::unique_ptr<SwapChain> Create(const WindowSystemInfo& wsi, VkSurfaceKHR surface, static std::unique_ptr<SwapChain> Create(const WindowSystemInfo& wsi, VkSurfaceKHR surface,

View file

@ -50,12 +50,12 @@ VULKAN_INSTANCE_ENTRY_POINT(vkGetPhysicalDeviceXlibPresentationSupportKHR, false
#endif #endif
#if defined(VK_USE_PLATFORM_DISPLAY_KHR) #if defined(VK_USE_PLATFORM_DISPLAY_KHR)
VULKAN_INSTANCE_ENTRY_POINT(vkCreateDisplayPlaneSurfaceKHR, true) VULKAN_INSTANCE_ENTRY_POINT(vkCreateDisplayPlaneSurfaceKHR, false)
VULKAN_INSTANCE_ENTRY_POINT(vkGetDisplayPlaneCapabilitiesKHR, true) VULKAN_INSTANCE_ENTRY_POINT(vkGetDisplayPlaneCapabilitiesKHR, false)
VULKAN_INSTANCE_ENTRY_POINT(vkGetPhysicalDeviceDisplayPlanePropertiesKHR, true) VULKAN_INSTANCE_ENTRY_POINT(vkGetPhysicalDeviceDisplayPlanePropertiesKHR, false)
VULKAN_INSTANCE_ENTRY_POINT(vkGetDisplayPlaneSupportedDisplaysKHR, true) VULKAN_INSTANCE_ENTRY_POINT(vkGetDisplayPlaneSupportedDisplaysKHR, false)
VULKAN_INSTANCE_ENTRY_POINT(vkGetDisplayModePropertiesKHR, true) VULKAN_INSTANCE_ENTRY_POINT(vkGetDisplayModePropertiesKHR, false)
VULKAN_INSTANCE_ENTRY_POINT(vkGetPhysicalDeviceDisplayPropertiesKHR, true) VULKAN_INSTANCE_ENTRY_POINT(vkGetPhysicalDeviceDisplayPropertiesKHR, false)
#endif #endif
#if defined(VK_USE_PLATFORM_ANDROID_KHR) #if defined(VK_USE_PLATFORM_ANDROID_KHR)

View file

@ -36,6 +36,7 @@ static void ResetVulkanLibraryFunctionPointers()
#define VULKAN_INSTANCE_ENTRY_POINT(name, required) name = nullptr; #define VULKAN_INSTANCE_ENTRY_POINT(name, required) name = nullptr;
#define VULKAN_DEVICE_ENTRY_POINT(name, required) name = nullptr; #define VULKAN_DEVICE_ENTRY_POINT(name, required) name = nullptr;
#include "VideoBackends/Vulkan/VulkanEntryPoints.inl" #include "VideoBackends/Vulkan/VulkanEntryPoints.inl"
#undef VULKAN_DEVICE_ENTRY_POINT #undef VULKAN_DEVICE_ENTRY_POINT
#undef VULKAN_INSTANCE_ENTRY_POINT #undef VULKAN_INSTANCE_ENTRY_POINT
#undef VULKAN_MODULE_ENTRY_POINT #undef VULKAN_MODULE_ENTRY_POINT
@ -108,6 +109,7 @@ bool LoadVulkanLibrary(bool force_system_library)
return false; \ return false; \
} }
#include "VideoBackends/Vulkan/VulkanEntryPoints.inl" #include "VideoBackends/Vulkan/VulkanEntryPoints.inl"
#undef VULKAN_MODULE_ENTRY_POINT #undef VULKAN_MODULE_ENTRY_POINT
return true; return true;
@ -135,6 +137,7 @@ bool LoadVulkanInstanceFunctions(VkInstance instance)
#define VULKAN_INSTANCE_ENTRY_POINT(name, required) \ #define VULKAN_INSTANCE_ENTRY_POINT(name, required) \
LoadFunction(reinterpret_cast<PFN_vkVoidFunction*>(&name), #name, required); LoadFunction(reinterpret_cast<PFN_vkVoidFunction*>(&name), #name, required);
#include "VideoBackends/Vulkan/VulkanEntryPoints.inl" #include "VideoBackends/Vulkan/VulkanEntryPoints.inl"
#undef VULKAN_INSTANCE_ENTRY_POINT #undef VULKAN_INSTANCE_ENTRY_POINT
return !required_functions_missing; return !required_functions_missing;
@ -155,6 +158,7 @@ bool LoadVulkanDeviceFunctions(VkDevice device)
#define VULKAN_DEVICE_ENTRY_POINT(name, required) \ #define VULKAN_DEVICE_ENTRY_POINT(name, required) \
LoadFunction(reinterpret_cast<PFN_vkVoidFunction*>(&name), #name, required); LoadFunction(reinterpret_cast<PFN_vkVoidFunction*>(&name), #name, required);
#include "VideoBackends/Vulkan/VulkanEntryPoints.inl" #include "VideoBackends/Vulkan/VulkanEntryPoints.inl"
#undef VULKAN_DEVICE_ENTRY_POINT #undef VULKAN_DEVICE_ENTRY_POINT
return !required_functions_missing; return !required_functions_missing;