Compare commits

...

7 Commits

Author SHA1 Message Date
Ellie Hermaszewska df0a62060f
Merge c611baac8c into 462165da19 2024-04-27 05:14:29 +08:00
Philip Rebohle 462165da19 [util] Add Deck profile for Fallout 4
Should fix the FPS problem on Deck OLED.
2024-04-26 14:34:08 +02:00
Philip Rebohle 3f27a0ee58 [util] Add a way to define app profiles exclusive to Steam Deck 2024-04-26 14:34:08 +02:00
Katharine Chui aac3396671 [dxgi] unchain DxgiFactory::CreateSwapChain and CreateSwapChainForHwnd
similar to https://github.com/doitsujin/dxvk/pull/3966, avoid
chaining so that dxgi tools attempting to wrap swapchains don't
end up double wrapping

ref: https://github.com/SpecialKO/SpecialK/issues/168
2024-04-25 12:07:50 +02:00
Ellie Hermaszewska c611baac8c
Use VK_EXT_headless_surface in wsi-none 2023-08-31 13:05:36 +08:00
Ellie Hermaszewska ca91095799
Remove wsi_common_src and dep_displayinfo from "none" wsi build 2023-08-31 13:05:36 +08:00
Ellie Hermaszewska 858dd3b487
Add None WSI 2023-08-31 13:05:36 +08:00
13 changed files with 294 additions and 10 deletions

View File

@ -6,6 +6,8 @@
#include "wsi/native_sdl2.h"
#elif DXVK_WSI_GLFW
#include "wsi/native_glfw.h"
#elif DXVK_WSI_NONE
//empty
#else
#error Unknown wsi!
#endif

View File

@ -136,6 +136,8 @@ else
elif dxvk_wsi == 'glfw'
lib_glfw = cpp.find_library('glfw')
compiler_args += ['-DDXVK_WSI_GLFW']
elif dxvk_wsi == 'none'
compiler_args += ['-DDXVK_WSI_NONE']
endif
dxvk_name_prefix = 'libdxvk_'

View File

@ -230,7 +230,7 @@ namespace dxvk {
descFs.Windowed = pDesc->Windowed;
IDXGISwapChain1* swapChain = nullptr;
HRESULT hr = CreateSwapChainForHwnd(
HRESULT hr = CreateSwapChainForHwndBase(
pDevice, pDesc->OutputWindow,
&desc, &descFs, nullptr,
&swapChain);
@ -244,6 +244,19 @@ namespace dxvk {
IUnknown* pDevice,
HWND hWnd,
const DXGI_SWAP_CHAIN_DESC1* pDesc,
const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc,
IDXGIOutput* pRestrictToOutput,
IDXGISwapChain1** ppSwapChain) {
return CreateSwapChainForHwndBase(
pDevice, hWnd,
pDesc, pFullscreenDesc, pRestrictToOutput,
ppSwapChain);
}
HRESULT STDMETHODCALLTYPE DxgiFactory::CreateSwapChainForHwndBase(
IUnknown* pDevice,
HWND hWnd,
const DXGI_SWAP_CHAIN_DESC1* pDesc,
const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc,
IDXGIOutput* pRestrictToOutput,
IDXGISwapChain1** ppSwapChain) {

View File

@ -200,6 +200,14 @@ namespace dxvk {
UINT m_flags;
BOOL m_monitorFallback;
HRESULT STDMETHODCALLTYPE CreateSwapChainForHwndBase(
IUnknown* pDevice,
HWND hWnd,
const DXGI_SWAP_CHAIN_DESC1* pDesc,
const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc,
IDXGIOutput* pRestrictToOutput,
IDXGISwapChain1** ppSwapChain);
};
}

View File

@ -129,6 +129,10 @@ elif dxvk_wsi == 'glfw'
dxvk_src += [
'platform/dxvk_glfw_exts.cpp'
]
elif dxvk_wsi == 'none'
dxvk_src += [
'platform/dxvk_none_exts.cpp'
]
endif
dxvk_extra_deps = [ dependency('threads') ]

View File

@ -0,0 +1,33 @@
#include "../dxvk_platform_exts.h"
namespace dxvk {
DxvkPlatformExts DxvkPlatformExts::s_instance;
std::string_view DxvkPlatformExts::getName() {
return "No WSI";
}
DxvkNameSet DxvkPlatformExts::getInstanceExtensions() {
return {};
}
DxvkNameSet DxvkPlatformExts::getDeviceExtensions(
uint32_t adapterId) {
return {};
}
void DxvkPlatformExts::initInstanceExtensions() {
}
void DxvkPlatformExts::initDeviceExtensions(
const DxvkInstance* instance) {
}
}

View File

@ -13,7 +13,10 @@
namespace dxvk {
const static std::vector<std::pair<const char*, Config>> g_appDefaults = {{
using ProfileList = std::vector<std::pair<const char*, Config>>;
const static ProfileList g_profiles = {{
/* Assassin's Creed Syndicate: amdags issues */
{ R"(\\ACS\.exe$)", {{
{ "dxgi.customVendorId", "10de" },
@ -909,6 +912,28 @@ namespace dxvk {
}};
const static ProfileList g_deckProfiles = {{
/* Fallout 4: Defaults to 45 FPS on OLED, but also breaks above 60 FPS */
{ R"(\\Fallout4\.exe$)", {{
{ "dxgi.syncInterval", "1" },
{ "dxgi.maxFrameRate", "60" },
}} },
}};
const Config* findProfile(const ProfileList& profiles, const std::string& appName) {
auto appConfig = std::find_if(profiles.begin(), profiles.end(),
[&appName] (const std::pair<const char*, Config>& pair) {
std::regex expr(pair.first, std::regex::extended | std::regex::icase);
return std::regex_search(appName, expr);
});
return appConfig != profiles.end()
? &appConfig->second
: nullptr;
}
static bool isWhitespace(char ch) {
return ch == ' ' || ch == '\x9' || ch == '\r';
}
@ -1158,20 +1183,22 @@ namespace dxvk {
Config Config::getAppConfig(const std::string& appName) {
auto appConfig = std::find_if(g_appDefaults.begin(), g_appDefaults.end(),
[&appName] (const std::pair<const char*, Config>& pair) {
std::regex expr(pair.first, std::regex::extended | std::regex::icase);
return std::regex_search(appName, expr);
});
const Config* config = nullptr;
if (appConfig != g_appDefaults.end()) {
if (env::getEnvVar("SteamDeck") == "1")
config = findProfile(g_deckProfiles, appName);
if (!config)
config = findProfile(g_profiles, appName);
if (config) {
// Inform the user that we loaded a default config
Logger::info(str::format("Found built-in config:"));
for (auto& pair : appConfig->second.m_options)
for (auto& pair : config->m_options)
Logger::info(str::format(" ", pair.first, " = ", pair.second));
return appConfig->second;
return *config;
}
return Config();

View File

@ -17,6 +17,12 @@ wsi_glfw_src = [
'glfw/wsi_window_glfw.cpp',
]
wsi_none_src = [
'none/wsi_monitor_none.cpp',
'none/wsi_window_none.cpp',
'none/wsi_edid_none.cpp',
]
if dxvk_wsi == 'win32'
wsi_src = wsi_common_src + wsi_win32_src
wsi_deps = [ dep_displayinfo ]
@ -26,6 +32,9 @@ elif dxvk_wsi == 'sdl2'
elif dxvk_wsi == 'glfw'
wsi_src = wsi_common_src + wsi_glfw_src
wsi_deps = [ dep_displayinfo, lib_glfw ]
elif dxvk_wsi == 'none'
wsi_src = wsi_none_src
wsi_deps = []
else
error('Unknown wsi')
endif

View File

@ -0,0 +1,10 @@
#include "wsi_edid.h"
namespace dxvk::wsi {
std::optional<WsiDisplayMetadata> parseColorimetryInfo(
const WsiEdidData& edidData) {
return std::nullopt;
}
}

View File

@ -0,0 +1,66 @@
#include "../wsi_monitor.h"
#include "wsi/native_wsi.h"
#include "wsi_platform_none.h"
#include "../../util/util_string.h"
#include "../../util/log/log.h"
namespace dxvk::wsi {
HMONITOR getDefaultMonitor() {
return nullptr;
}
HMONITOR enumMonitors(uint32_t index) {
return nullptr;
}
HMONITOR enumMonitors(const LUID *adapterLUID[], uint32_t numLUIDs, uint32_t index) {
return enumMonitors(index);
}
bool getDisplayName(
HMONITOR hMonitor,
WCHAR (&Name)[32]) {
return false;
}
bool getDesktopCoordinates(
HMONITOR hMonitor,
RECT* pRect) {
return false;
}
bool getDisplayMode(
HMONITOR hMonitor,
uint32_t ModeNumber,
WsiMode* pMode) {
return false;
}
bool getCurrentDisplayMode(
HMONITOR hMonitor,
WsiMode* pMode) {
return false;
}
bool getDesktopDisplayMode(
HMONITOR hMonitor,
WsiMode* pMode) {
return false;
}
std::vector<uint8_t> getMonitorEdid(HMONITOR hMonitor) {
Logger::err("getMonitorEdid not implemented on this platform.");
return {};
}
}

View File

@ -0,0 +1,17 @@
#pragma once
#include "../wsi_monitor.h"
namespace dxvk::wsi {
/**
* \brief Impl-dependent state
*/
struct DxvkWindowState {
};
inline bool isDisplayValid(int32_t displayId) {
return false;
}
}

View File

@ -0,0 +1,91 @@
#include "../wsi_window.h"
#include "native/wsi/native_wsi.h"
#include "wsi_platform_none.h"
#include "../../util/util_string.h"
#include "../../util/log/log.h"
namespace dxvk::wsi {
void getWindowSize(
HWND hWindow,
uint32_t* pWidth,
uint32_t* pHeight) {
}
void resizeWindow(
HWND hWindow,
DxvkWindowState* pState,
uint32_t Width,
uint32_t Height) {
}
bool setWindowMode(
HMONITOR hMonitor,
HWND hWindow,
const WsiMode& pMode) {
return false;
}
bool enterFullscreenMode(
HMONITOR hMonitor,
HWND hWindow,
DxvkWindowState* pState,
bool ModeSwitch) {
return false;
}
bool leaveFullscreenMode(
HWND hWindow,
DxvkWindowState* pState,
bool restoreCoordinates) {
return false;
}
bool restoreDisplayMode() {
return false;
}
HMONITOR getWindowMonitor(HWND hWindow) {
return nullptr;
}
bool isWindow(HWND hWindow) {
return false;
}
void updateFullscreenWindow(
HMONITOR hMonitor,
HWND hWindow,
bool forceTopmost) {
}
VkResult createSurface(
HWND hWindow,
PFN_vkGetInstanceProcAddr pfnVkGetInstanceProcAddr,
VkInstance instance,
VkSurfaceKHR* pSurface) {
auto pfnVkCreateHeadlessSurfaceEXT = reinterpret_cast<PFN_vkCreateHeadlessSurfaceEXT>(
pfnVkGetInstanceProcAddr(instance, "vkCreateHeadlessSurfaceEXT"));
if (!pfnVkCreateHeadlessSurfaceEXT)
return VK_ERROR_FEATURE_NOT_PRESENT;
VkHeadlessSurfaceCreateInfoEXT info = { VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT };
info.pNext = nullptr;
info.flags = 0;
return pfnVkCreateHeadlessSurfaceEXT(instance, &info, nullptr, pSurface);
}
}

View File

@ -6,4 +6,6 @@
#include "sdl2/wsi_platform_sdl2.h"
#elif defined(DXVK_WSI_GLFW)
#include "glfw/wsi_platform_glfw.h"
#elif defined(DXVK_WSI_NONE)
#include "none/wsi_platform_none.h"
#endif