mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-04 16:32:39 +00:00
Merge branch 'main' into game_folder_fix
This commit is contained in:
commit
b0e7c3d379
2
.github/linux-appimage-qt.sh
vendored
2
.github/linux-appimage-qt.sh
vendored
@ -9,6 +9,8 @@ fi
|
|||||||
|
|
||||||
export Qt6_DIR="/usr/lib/qt6"
|
export Qt6_DIR="/usr/lib/qt6"
|
||||||
export PATH="$Qt6_DIR/bin:$PATH"
|
export PATH="$Qt6_DIR/bin:$PATH"
|
||||||
|
export EXTRA_QT_PLUGINS="waylandcompositor"
|
||||||
|
export EXTRA_PLATFORM_PLUGINS="libqwayland-egl.so;libqwayland-generic.so"
|
||||||
|
|
||||||
# Prepare Tools for building the AppImage
|
# Prepare Tools for building the AppImage
|
||||||
wget -q https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
|
wget -q https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
|
||||||
|
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -287,7 +287,7 @@ jobs:
|
|||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libfuse2 clang build-essential libasound2-dev libpulse-dev libopenal-dev
|
run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libdecor-0-dev libxkbcommon-dev libglfw3-dev libgles2-mesa-dev libfuse2 clang build-essential libasound2-dev libpulse-dev libopenal-dev
|
||||||
|
|
||||||
- name: Cache CMake Configuration
|
- name: Cache CMake Configuration
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
@ -343,7 +343,7 @@ jobs:
|
|||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libfuse2 clang build-essential qt6-base-dev qt6-tools-dev qt6-multimedia-dev libasound2-dev libpulse-dev libopenal-dev
|
run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libdecor-0-dev libxkbcommon-dev libglfw3-dev libgles2-mesa-dev libfuse2 clang build-essential qt6-base-dev qt6-tools-dev qt6-multimedia-dev libasound2-dev libpulse-dev libopenal-dev
|
||||||
|
|
||||||
- name: Cache CMake Configuration
|
- name: Cache CMake Configuration
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
|
@ -324,6 +324,10 @@ set(USBD_LIB src/core/libraries/usbd/usbd.cpp
|
|||||||
src/core/libraries/usbd/usbd.h
|
src/core/libraries/usbd/usbd.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(FIBER_LIB src/core/libraries/fiber/fiber.cpp
|
||||||
|
src/core/libraries/fiber/fiber.h
|
||||||
|
)
|
||||||
|
|
||||||
set(NP_LIBS src/core/libraries/np_manager/np_manager.cpp
|
set(NP_LIBS src/core/libraries/np_manager/np_manager.cpp
|
||||||
src/core/libraries/np_manager/np_manager.h
|
src/core/libraries/np_manager/np_manager.h
|
||||||
src/core/libraries/np_score/np_score.cpp
|
src/core/libraries/np_score/np_score.cpp
|
||||||
@ -464,6 +468,7 @@ set(CORE src/core/aerolib/stubs.cpp
|
|||||||
${USBD_LIB}
|
${USBD_LIB}
|
||||||
${MISC_LIBS}
|
${MISC_LIBS}
|
||||||
${DIALOGS_LIB}
|
${DIALOGS_LIB}
|
||||||
|
${FIBER_LIB}
|
||||||
${DEV_TOOLS}
|
${DEV_TOOLS}
|
||||||
src/core/debug_state.cpp
|
src/core/debug_state.cpp
|
||||||
src/core/debug_state.h
|
src/core/debug_state.h
|
||||||
|
@ -483,7 +483,6 @@ void load(const std::filesystem::path& path) {
|
|||||||
}
|
}
|
||||||
isShowSplash = toml::find_or<bool>(general, "showSplash", true);
|
isShowSplash = toml::find_or<bool>(general, "showSplash", true);
|
||||||
isAutoUpdate = toml::find_or<bool>(general, "autoUpdate", false);
|
isAutoUpdate = toml::find_or<bool>(general, "autoUpdate", false);
|
||||||
backButtonBehavior = toml::find_or<std::string>(general, "backButtonBehavior", "left");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.contains("Input")) {
|
if (data.contains("Input")) {
|
||||||
@ -491,6 +490,7 @@ void load(const std::filesystem::path& path) {
|
|||||||
|
|
||||||
cursorState = toml::find_or<int>(input, "cursorState", HideCursorState::Idle);
|
cursorState = toml::find_or<int>(input, "cursorState", HideCursorState::Idle);
|
||||||
cursorHideTimeout = toml::find_or<int>(input, "cursorHideTimeout", 5);
|
cursorHideTimeout = toml::find_or<int>(input, "cursorHideTimeout", 5);
|
||||||
|
backButtonBehavior = toml::find_or<std::string>(input, "backButtonBehavior", "left");
|
||||||
useSpecialPad = toml::find_or<bool>(input, "useSpecialPad", false);
|
useSpecialPad = toml::find_or<bool>(input, "useSpecialPad", false);
|
||||||
specialPadClass = toml::find_or<int>(input, "specialPadClass", 1);
|
specialPadClass = toml::find_or<int>(input, "specialPadClass", 1);
|
||||||
}
|
}
|
||||||
@ -602,7 +602,7 @@ void save(const std::filesystem::path& path) {
|
|||||||
data["General"]["autoUpdate"] = isAutoUpdate;
|
data["General"]["autoUpdate"] = isAutoUpdate;
|
||||||
data["Input"]["cursorState"] = cursorState;
|
data["Input"]["cursorState"] = cursorState;
|
||||||
data["Input"]["cursorHideTimeout"] = cursorHideTimeout;
|
data["Input"]["cursorHideTimeout"] = cursorHideTimeout;
|
||||||
data["General"]["backButtonBehavior"] = backButtonBehavior;
|
data["Input"]["backButtonBehavior"] = backButtonBehavior;
|
||||||
data["Input"]["useSpecialPad"] = useSpecialPad;
|
data["Input"]["useSpecialPad"] = useSpecialPad;
|
||||||
data["Input"]["specialPadClass"] = specialPadClass;
|
data["Input"]["specialPadClass"] = specialPadClass;
|
||||||
data["GPU"]["screenWidth"] = screenWidth;
|
data["GPU"]["screenWidth"] = screenWidth;
|
||||||
@ -658,8 +658,6 @@ void setDefaultValues() {
|
|||||||
playBGM = false;
|
playBGM = false;
|
||||||
BGMvolume = 50;
|
BGMvolume = 50;
|
||||||
enableDiscordRPC = true;
|
enableDiscordRPC = true;
|
||||||
cursorState = HideCursorState::Idle;
|
|
||||||
cursorHideTimeout = 5;
|
|
||||||
screenWidth = 1280;
|
screenWidth = 1280;
|
||||||
screenHeight = 720;
|
screenHeight = 720;
|
||||||
logFilter = "";
|
logFilter = "";
|
||||||
@ -670,6 +668,8 @@ void setDefaultValues() {
|
|||||||
} else {
|
} else {
|
||||||
updateChannel = "Nightly";
|
updateChannel = "Nightly";
|
||||||
}
|
}
|
||||||
|
cursorState = HideCursorState::Idle;
|
||||||
|
cursorHideTimeout = 5;
|
||||||
backButtonBehavior = "left";
|
backButtonBehavior = "left";
|
||||||
useSpecialPad = false;
|
useSpecialPad = false;
|
||||||
specialPadClass = 1;
|
specialPadClass = 1;
|
||||||
|
@ -20,15 +20,14 @@ bool getPlayBGM();
|
|||||||
int getBGMvolume();
|
int getBGMvolume();
|
||||||
bool getEnableDiscordRPC();
|
bool getEnableDiscordRPC();
|
||||||
|
|
||||||
s16 getCursorState();
|
|
||||||
int getCursorHideTimeout();
|
|
||||||
|
|
||||||
std::string getLogFilter();
|
std::string getLogFilter();
|
||||||
std::string getLogType();
|
std::string getLogType();
|
||||||
std::string getUserName();
|
std::string getUserName();
|
||||||
std::string getUpdateChannel();
|
std::string getUpdateChannel();
|
||||||
std::string getBackButtonBehavior();
|
|
||||||
|
|
||||||
|
s16 getCursorState();
|
||||||
|
int getCursorHideTimeout();
|
||||||
|
std::string getBackButtonBehavior();
|
||||||
bool getUseSpecialPad();
|
bool getUseSpecialPad();
|
||||||
int getSpecialPadClass();
|
int getSpecialPadClass();
|
||||||
|
|
||||||
@ -59,14 +58,14 @@ void setFullscreenMode(bool enable);
|
|||||||
void setPlayBGM(bool enable);
|
void setPlayBGM(bool enable);
|
||||||
void setBGMvolume(int volume);
|
void setBGMvolume(int volume);
|
||||||
void setEnableDiscordRPC(bool enable);
|
void setEnableDiscordRPC(bool enable);
|
||||||
void setCursorState(s16 cursorState);
|
|
||||||
void setCursorHideTimeout(int newcursorHideTimeout);
|
|
||||||
void setLanguage(u32 language);
|
void setLanguage(u32 language);
|
||||||
void setNeoMode(bool enable);
|
void setNeoMode(bool enable);
|
||||||
void setUserName(const std::string& type);
|
void setUserName(const std::string& type);
|
||||||
void setUpdateChannel(const std::string& type);
|
void setUpdateChannel(const std::string& type);
|
||||||
void setBackButtonBehavior(const std::string& type);
|
|
||||||
|
|
||||||
|
void setCursorState(s16 cursorState);
|
||||||
|
void setCursorHideTimeout(int newcursorHideTimeout);
|
||||||
|
void setBackButtonBehavior(const std::string& type);
|
||||||
void setUseSpecialPad(bool use);
|
void setUseSpecialPad(bool use);
|
||||||
void setSpecialPadClass(int type);
|
void setSpecialPadClass(int type);
|
||||||
|
|
||||||
|
@ -114,6 +114,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
|
|||||||
SUB(Lib, AvPlayer) \
|
SUB(Lib, AvPlayer) \
|
||||||
SUB(Lib, Ngs2) \
|
SUB(Lib, Ngs2) \
|
||||||
SUB(Lib, Audio3d) \
|
SUB(Lib, Audio3d) \
|
||||||
|
SUB(Lib, Fiber) \
|
||||||
CLS(Frontend) \
|
CLS(Frontend) \
|
||||||
CLS(Render) \
|
CLS(Render) \
|
||||||
SUB(Render, Vulkan) \
|
SUB(Render, Vulkan) \
|
||||||
|
@ -81,6 +81,7 @@ enum class Class : u8 {
|
|||||||
Lib_AvPlayer, ///< The LibSceAvPlayer implementation.
|
Lib_AvPlayer, ///< The LibSceAvPlayer implementation.
|
||||||
Lib_Ngs2, ///< The LibSceNgs2 implementation.
|
Lib_Ngs2, ///< The LibSceNgs2 implementation.
|
||||||
Lib_Audio3d, ///< The LibSceAudio3d implementation.
|
Lib_Audio3d, ///< The LibSceAudio3d implementation.
|
||||||
|
Lib_Fiber, ///< The LibSceFiber implementation.
|
||||||
Frontend, ///< Emulator UI
|
Frontend, ///< Emulator UI
|
||||||
Render, ///< Video Core
|
Render, ///< Video Core
|
||||||
Render_Vulkan, ///< Vulkan backend
|
Render_Vulkan, ///< Vulkan backend
|
||||||
|
@ -95,6 +95,18 @@ static auto UserPaths = [] {
|
|||||||
user_dir =
|
user_dir =
|
||||||
std::filesystem::path(getenv("HOME")) / "Library" / "Application Support" / "shadPS4";
|
std::filesystem::path(getenv("HOME")) / "Library" / "Application Support" / "shadPS4";
|
||||||
}
|
}
|
||||||
|
#elif defined(__linux__)
|
||||||
|
auto user_dir = std::filesystem::current_path() / PORTABLE_DIR;
|
||||||
|
// Check if the "user" directory exists in the current path:
|
||||||
|
if (!std::filesystem::exists(user_dir)) {
|
||||||
|
// If it doesn't exist, use XDG_DATA_HOME if it is set, and provide a standard default
|
||||||
|
const char* xdg_data_home = getenv("XDG_DATA_HOME");
|
||||||
|
if (xdg_data_home != nullptr && strlen(xdg_data_home) > 0) {
|
||||||
|
user_dir = std::filesystem::path(xdg_data_home) / "shadPS4";
|
||||||
|
} else {
|
||||||
|
user_dir = std::filesystem::path(getenv("HOME")) / ".local" / "share" / "shadPS4";
|
||||||
|
}
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
const auto user_dir = std::filesystem::current_path() / PORTABLE_DIR;
|
const auto user_dir = std::filesystem::current_path() / PORTABLE_DIR;
|
||||||
#endif
|
#endif
|
||||||
|
@ -499,3 +499,11 @@ constexpr int ORBIS_AVPLAYER_ERROR_INFO_OTHER_ENCRY = 0x806A00BF;
|
|||||||
constexpr int ORBIS_APP_CONTENT_ERROR_PARAMETER = 0x80D90002;
|
constexpr int ORBIS_APP_CONTENT_ERROR_PARAMETER = 0x80D90002;
|
||||||
constexpr int ORBIS_APP_CONTENT_ERROR_DRM_NO_ENTITLEMENT = 0x80D90007;
|
constexpr int ORBIS_APP_CONTENT_ERROR_DRM_NO_ENTITLEMENT = 0x80D90007;
|
||||||
constexpr int ORBIS_APP_CONTENT_ERROR_NOT_FOUND = 0x80D90005;
|
constexpr int ORBIS_APP_CONTENT_ERROR_NOT_FOUND = 0x80D90005;
|
||||||
|
|
||||||
|
// Fiber library
|
||||||
|
constexpr int ORBIS_FIBER_ERROR_NULL = 0x80590001;
|
||||||
|
constexpr int ORBIS_FIBER_ERROR_ALIGNMENT = 0x80590002;
|
||||||
|
constexpr int ORBIS_FIBER_ERROR_RANGE = 0x80590003;
|
||||||
|
constexpr int ORBIS_FIBER_ERROR_INVALID = 0x80590004;
|
||||||
|
constexpr int ORBIS_FIBER_ERROR_PERMISSION = 0x80590005;
|
||||||
|
constexpr int ORBIS_FIBER_ERROR_STATE = 0x80590006;
|
284
src/core/libraries/fiber/fiber.cpp
Normal file
284
src/core/libraries/fiber/fiber.cpp
Normal file
@ -0,0 +1,284 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "fiber.h"
|
||||||
|
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "common/singleton.h"
|
||||||
|
#include "core/libraries/error_codes.h"
|
||||||
|
#include "core/libraries/libs.h"
|
||||||
|
#include "core/linker.h"
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Libraries::Fiber {
|
||||||
|
|
||||||
|
constexpr static u64 kFiberSignature = 0x054ad954;
|
||||||
|
|
||||||
|
thread_local SceFiber* gCurrentFiber = nullptr;
|
||||||
|
thread_local void* gFiberThread = nullptr;
|
||||||
|
|
||||||
|
void FiberEntry(void* param) {
|
||||||
|
SceFiber* fiber = static_cast<SceFiber*>(param);
|
||||||
|
u64 argRun = 0;
|
||||||
|
u64 argRet = 0;
|
||||||
|
|
||||||
|
gCurrentFiber = fiber;
|
||||||
|
|
||||||
|
if (fiber->pArgRun != nullptr) {
|
||||||
|
argRun = *fiber->pArgRun;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||||
|
linker->ExecuteGuest(fiber->entry, fiber->argOnInitialize, argRun);
|
||||||
|
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberInitialize(SceFiber* fiber, const char* name, SceFiberEntry entry,
|
||||||
|
u64 argOnInitialize, void* addrContext, u64 sizeContext,
|
||||||
|
const SceFiberOptParam* optParam) {
|
||||||
|
LOG_INFO(Lib_Fiber, "called: name = {}", name);
|
||||||
|
|
||||||
|
if (!fiber || !name || !entry) {
|
||||||
|
return ORBIS_FIBER_ERROR_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fiber->signature = kFiberSignature;
|
||||||
|
|
||||||
|
fiber->entry = entry;
|
||||||
|
fiber->argOnInitialize = argOnInitialize;
|
||||||
|
|
||||||
|
fiber->argRun = 0;
|
||||||
|
fiber->pArgRun = &fiber->argRun;
|
||||||
|
fiber->argReturn = 0;
|
||||||
|
fiber->pArgReturn = &fiber->argReturn;
|
||||||
|
|
||||||
|
fiber->sizeContext = sizeContext;
|
||||||
|
|
||||||
|
fiber->state = FiberState::Init;
|
||||||
|
#ifdef _WIN64
|
||||||
|
fiber->handle = CreateFiber(sizeContext, FiberEntry, fiber);
|
||||||
|
#else
|
||||||
|
UNREACHABLE_MSG("Missing implementation");
|
||||||
|
#endif
|
||||||
|
strncpy(fiber->name, name, ORBIS_FIBER_MAX_NAME_LENGTH);
|
||||||
|
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberOptParamInitialize(SceFiberOptParam* optParam) {
|
||||||
|
LOG_ERROR(Lib_Fiber, "called");
|
||||||
|
|
||||||
|
if (!optParam) {
|
||||||
|
return ORBIS_FIBER_ERROR_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberFinalize(SceFiber* fiber) {
|
||||||
|
LOG_TRACE(Lib_Fiber, "called");
|
||||||
|
|
||||||
|
if (!fiber) {
|
||||||
|
return ORBIS_FIBER_ERROR_NULL;
|
||||||
|
}
|
||||||
|
if ((u64)fiber % 8 != 0) {
|
||||||
|
return ORBIS_FIBER_ERROR_ALIGNMENT;
|
||||||
|
}
|
||||||
|
if (fiber->signature != kFiberSignature) {
|
||||||
|
return ORBIS_FIBER_ERROR_INVALID;
|
||||||
|
}
|
||||||
|
if (fiber->state != FiberState::Run) {
|
||||||
|
return ORBIS_FIBER_ERROR_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fiber->signature = 0;
|
||||||
|
fiber->state = FiberState::None;
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
DeleteFiber(fiber->handle);
|
||||||
|
#else
|
||||||
|
UNREACHABLE_MSG("Missing implementation");
|
||||||
|
#endif
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberRun(SceFiber* fiber, u64 argOnRunTo, u64* argOnReturn) {
|
||||||
|
LOG_TRACE(Lib_Fiber, "called");
|
||||||
|
|
||||||
|
if (!fiber) {
|
||||||
|
return ORBIS_FIBER_ERROR_NULL;
|
||||||
|
}
|
||||||
|
if ((u64)fiber % 8 != 0) {
|
||||||
|
return ORBIS_FIBER_ERROR_ALIGNMENT;
|
||||||
|
}
|
||||||
|
if (fiber->signature != kFiberSignature) {
|
||||||
|
return ORBIS_FIBER_ERROR_INVALID;
|
||||||
|
}
|
||||||
|
if (fiber->state == FiberState::Run) {
|
||||||
|
return ORBIS_FIBER_ERROR_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gFiberThread == nullptr) {
|
||||||
|
#ifdef _WIN64
|
||||||
|
gFiberThread = ConvertThreadToFiber(nullptr);
|
||||||
|
#else
|
||||||
|
UNREACHABLE_MSG("Missing implementation");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
gCurrentFiber = fiber;
|
||||||
|
|
||||||
|
if (fiber->pArgRun != nullptr) {
|
||||||
|
*fiber->pArgRun = argOnRunTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
fiber->pArgReturn = argOnReturn;
|
||||||
|
fiber->state = FiberState::Run;
|
||||||
|
#ifdef _WIN64
|
||||||
|
SwitchToFiber(fiber->handle);
|
||||||
|
#else
|
||||||
|
UNREACHABLE_MSG("Missing implementation");
|
||||||
|
#endif
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberSwitch(SceFiber* fiber, u64 argOnRunTo, u64* argOnRun) {
|
||||||
|
LOG_TRACE(Lib_Fiber, "called");
|
||||||
|
|
||||||
|
if (!fiber) {
|
||||||
|
return ORBIS_FIBER_ERROR_NULL;
|
||||||
|
}
|
||||||
|
if ((u64)fiber % 8 != 0) {
|
||||||
|
return ORBIS_FIBER_ERROR_ALIGNMENT;
|
||||||
|
}
|
||||||
|
if (fiber->signature != kFiberSignature) {
|
||||||
|
return ORBIS_FIBER_ERROR_INVALID;
|
||||||
|
}
|
||||||
|
if (gCurrentFiber == nullptr) {
|
||||||
|
return ORBIS_FIBER_ERROR_PERMISSION;
|
||||||
|
}
|
||||||
|
if (fiber->state == FiberState::Run) {
|
||||||
|
return ORBIS_FIBER_ERROR_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gCurrentFiber->state = FiberState::Suspend;
|
||||||
|
|
||||||
|
// TODO: argOnRun
|
||||||
|
|
||||||
|
*fiber->pArgRun = argOnRunTo;
|
||||||
|
fiber->state = FiberState::Run;
|
||||||
|
|
||||||
|
gCurrentFiber = fiber;
|
||||||
|
#ifdef _WIN64
|
||||||
|
SwitchToFiber(fiber->handle);
|
||||||
|
#else
|
||||||
|
UNREACHABLE_MSG("Missing implementation");
|
||||||
|
#endif
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberGetSelf(SceFiber** fiber) {
|
||||||
|
LOG_TRACE(Lib_Fiber, "called");
|
||||||
|
|
||||||
|
if (!fiber || !gCurrentFiber) {
|
||||||
|
return ORBIS_FIBER_ERROR_NULL;
|
||||||
|
}
|
||||||
|
if (gCurrentFiber->signature != kFiberSignature) {
|
||||||
|
return ORBIS_FIBER_ERROR_PERMISSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
*fiber = gCurrentFiber;
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberReturnToThread(u64 argOnReturn, u64* argOnRun) {
|
||||||
|
LOG_TRACE(Lib_Fiber, "called");
|
||||||
|
|
||||||
|
if (gCurrentFiber->signature != kFiberSignature) {
|
||||||
|
return ORBIS_FIBER_ERROR_PERMISSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gCurrentFiber->pArgReturn != nullptr) {
|
||||||
|
*gCurrentFiber->pArgReturn = argOnReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: argOnRun
|
||||||
|
gCurrentFiber->state = FiberState::Suspend;
|
||||||
|
gCurrentFiber = nullptr;
|
||||||
|
#ifdef _WIN64
|
||||||
|
SwitchToFiber(gFiberThread);
|
||||||
|
#else
|
||||||
|
UNREACHABLE_MSG("Missing implementation");
|
||||||
|
#endif
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberGetInfo(SceFiber* fiber, SceFiberInfo* fiberInfo) {
|
||||||
|
LOG_INFO(Lib_Fiber, "called");
|
||||||
|
|
||||||
|
if (!fiber || !fiberInfo) {
|
||||||
|
return ORBIS_FIBER_ERROR_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fiberInfo->entry = fiber->entry;
|
||||||
|
fiberInfo->argOnInitialize = fiber->argOnInitialize;
|
||||||
|
fiberInfo->addrContext = nullptr;
|
||||||
|
fiberInfo->sizeContext = fiber->sizeContext;
|
||||||
|
fiberInfo->sizeContextMargin = 0;
|
||||||
|
|
||||||
|
strncpy(fiberInfo->name, fiber->name, ORBIS_FIBER_MAX_NAME_LENGTH);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberStartContextSizeCheck(u32 flags) {
|
||||||
|
LOG_ERROR(Lib_Fiber, "called");
|
||||||
|
|
||||||
|
if (flags != 0) {
|
||||||
|
return ORBIS_FIBER_ERROR_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberStopContextSizeCheck() {
|
||||||
|
LOG_ERROR(Lib_Fiber, "called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberRename(SceFiber* fiber, const char* name) {
|
||||||
|
LOG_INFO(Lib_Fiber, "called, name = {}", name);
|
||||||
|
|
||||||
|
if (!fiber || !name) {
|
||||||
|
return ORBIS_FIBER_ERROR_NULL;
|
||||||
|
}
|
||||||
|
if ((u64)fiber % 8 != 0) {
|
||||||
|
return ORBIS_FIBER_ERROR_ALIGNMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(fiber->name, name, ORBIS_FIBER_MAX_NAME_LENGTH);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterlibSceFiber(Core::Loader::SymbolsResolver* sym) {
|
||||||
|
LIB_FUNCTION("hVYD7Ou2pCQ", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberInitialize);
|
||||||
|
LIB_FUNCTION("asjUJJ+aa8s", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberOptParamInitialize);
|
||||||
|
LIB_FUNCTION("JeNX5F-NzQU", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberFinalize);
|
||||||
|
|
||||||
|
LIB_FUNCTION("a0LLrZWac0M", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberRun);
|
||||||
|
LIB_FUNCTION("PFT2S-tJ7Uk", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberSwitch);
|
||||||
|
LIB_FUNCTION("p+zLIOg27zU", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberGetSelf);
|
||||||
|
LIB_FUNCTION("B0ZX2hx9DMw", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberReturnToThread);
|
||||||
|
|
||||||
|
LIB_FUNCTION("uq2Y5BFz0PE", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberGetInfo);
|
||||||
|
LIB_FUNCTION("Lcqty+QNWFc", "libSceFiber", 1, "libSceFiber", 1, 1,
|
||||||
|
sceFiberStartContextSizeCheck);
|
||||||
|
LIB_FUNCTION("Kj4nXMpnM8Y", "libSceFiber", 1, "libSceFiber", 1, 1,
|
||||||
|
sceFiberStopContextSizeCheck);
|
||||||
|
LIB_FUNCTION("JzyT91ucGDc", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberRename);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Libraries::Fiber
|
83
src/core/libraries/fiber/fiber.h
Normal file
83
src/core/libraries/fiber/fiber.h
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/assert.h"
|
||||||
|
#include "common/types.h"
|
||||||
|
|
||||||
|
namespace Core::Loader {
|
||||||
|
class SymbolsResolver;
|
||||||
|
}
|
||||||
|
namespace Libraries::Fiber {
|
||||||
|
|
||||||
|
#define ORBIS_FIBER_MAX_NAME_LENGTH (31)
|
||||||
|
|
||||||
|
typedef void PS4_SYSV_ABI (*SceFiberEntry)(u64 argOnInitialize, u64 argOnRun);
|
||||||
|
|
||||||
|
enum FiberState : u32 {
|
||||||
|
None = 0u,
|
||||||
|
Init = 1u,
|
||||||
|
Run = 2u,
|
||||||
|
Suspend = 3u,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SceFiber {
|
||||||
|
u64 signature;
|
||||||
|
FiberState state;
|
||||||
|
SceFiberEntry entry;
|
||||||
|
|
||||||
|
u64 argOnInitialize;
|
||||||
|
|
||||||
|
u64 argRun;
|
||||||
|
u64* pArgRun;
|
||||||
|
|
||||||
|
u64 argReturn;
|
||||||
|
u64* pArgReturn;
|
||||||
|
|
||||||
|
u64 sizeContext;
|
||||||
|
|
||||||
|
char name[ORBIS_FIBER_MAX_NAME_LENGTH];
|
||||||
|
void* handle;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SceFiber) <= 256);
|
||||||
|
|
||||||
|
struct SceFiberInfo {
|
||||||
|
u64 size;
|
||||||
|
SceFiberEntry entry;
|
||||||
|
u64 argOnInitialize;
|
||||||
|
void* addrContext;
|
||||||
|
u64 sizeContext;
|
||||||
|
char name[ORBIS_FIBER_MAX_NAME_LENGTH + 1];
|
||||||
|
u64 sizeContextMargin;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(SceFiberInfo) <= 128);
|
||||||
|
|
||||||
|
typedef void* SceFiberOptParam;
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberInitialize(SceFiber* fiber, const char* name, SceFiberEntry entry,
|
||||||
|
u64 argOnInitialize, void* addrContext, u64 sizeContext,
|
||||||
|
const SceFiberOptParam* optParam);
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberOptParamInitialize(SceFiberOptParam* optParam);
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberFinalize(SceFiber* fiber);
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberRun(SceFiber* fiber, u64 argOnRunTo, u64* argOnReturn);
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberSwitch(SceFiber* fiber, u64 argOnRunTo, u64* argOnRun);
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberGetSelf(SceFiber** fiber);
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberReturnToThread(u64 argOnReturn, u64* argOnRun);
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberGetInfo(SceFiber* fiber, SceFiberInfo* fiberInfo);
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberStartContextSizeCheck(u32 flags);
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberStopContextSizeCheck(void);
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceFiberRename(SceFiber* fiber, const char* name);
|
||||||
|
|
||||||
|
void RegisterlibSceFiber(Core::Loader::SymbolsResolver* sym);
|
||||||
|
} // namespace Libraries::Fiber
|
@ -1076,10 +1076,28 @@ s32 PS4_SYSV_ABI sceGnmInsertPopMarker(u32* cmdbuf, u32 size) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceGnmInsertPushColorMarker() {
|
s32 PS4_SYSV_ABI sceGnmInsertPushColorMarker(u32* cmdbuf, u32 size, const char* marker, u32 color) {
|
||||||
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
|
LOG_TRACE(Lib_GnmDriver, "called");
|
||||||
|
|
||||||
|
if (cmdbuf && marker) {
|
||||||
|
const auto len = std::strlen(marker);
|
||||||
|
const u32 packet_size = ((len + 0xc) >> 2) + ((len + 0x10) >> 3) * 2;
|
||||||
|
if (packet_size + 2 == size) {
|
||||||
|
auto* nop = reinterpret_cast<PM4CmdNop*>(cmdbuf);
|
||||||
|
nop->header =
|
||||||
|
PM4Type3Header{PM4ItOpcode::Nop, packet_size, PM4ShaderType::ShaderGraphics};
|
||||||
|
nop->data_block[0] = PM4CmdNop::PayloadType::DebugColorMarkerPush;
|
||||||
|
const auto marker_len = len + 1;
|
||||||
|
std::memcpy(&nop->data_block[1], marker, marker_len);
|
||||||
|
*reinterpret_cast<u32*>(reinterpret_cast<u8*>(&nop->data_block[1]) + marker_len + 8) =
|
||||||
|
color;
|
||||||
|
std::memset(reinterpret_cast<u8*>(&nop->data_block[1]) + marker_len + 8 + sizeof(u32),
|
||||||
|
0, packet_size * 4 - marker_len - 8 - sizeof(u32));
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceGnmInsertPushMarker(u32* cmdbuf, u32 size, const char* marker) {
|
s32 PS4_SYSV_ABI sceGnmInsertPushMarker(u32* cmdbuf, u32 size, const char* marker) {
|
||||||
LOG_TRACE(Lib_GnmDriver, "called");
|
LOG_TRACE(Lib_GnmDriver, "called");
|
||||||
|
@ -105,7 +105,7 @@ int PS4_SYSV_ABI sceGnmGpuPaDebugEnter();
|
|||||||
int PS4_SYSV_ABI sceGnmGpuPaDebugLeave();
|
int PS4_SYSV_ABI sceGnmGpuPaDebugLeave();
|
||||||
int PS4_SYSV_ABI sceGnmInsertDingDongMarker();
|
int PS4_SYSV_ABI sceGnmInsertDingDongMarker();
|
||||||
s32 PS4_SYSV_ABI sceGnmInsertPopMarker(u32* cmdbuf, u32 size);
|
s32 PS4_SYSV_ABI sceGnmInsertPopMarker(u32* cmdbuf, u32 size);
|
||||||
int PS4_SYSV_ABI sceGnmInsertPushColorMarker();
|
s32 PS4_SYSV_ABI sceGnmInsertPushColorMarker(u32* cmdbuf, u32 size, const char* marker, u32 color);
|
||||||
s32 PS4_SYSV_ABI sceGnmInsertPushMarker(u32* cmdbuf, u32 size, const char* marker);
|
s32 PS4_SYSV_ABI sceGnmInsertPushMarker(u32* cmdbuf, u32 size, const char* marker);
|
||||||
int PS4_SYSV_ABI sceGnmInsertSetColorMarker();
|
int PS4_SYSV_ABI sceGnmInsertSetColorMarker();
|
||||||
int PS4_SYSV_ABI sceGnmInsertSetMarker();
|
int PS4_SYSV_ABI sceGnmInsertSetMarker();
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "core/libraries/dialogs/error_dialog.h"
|
#include "core/libraries/dialogs/error_dialog.h"
|
||||||
#include "core/libraries/dialogs/ime_dialog.h"
|
#include "core/libraries/dialogs/ime_dialog.h"
|
||||||
#include "core/libraries/disc_map/disc_map.h"
|
#include "core/libraries/disc_map/disc_map.h"
|
||||||
|
#include "core/libraries/fiber/fiber.h"
|
||||||
#include "core/libraries/gnmdriver/gnmdriver.h"
|
#include "core/libraries/gnmdriver/gnmdriver.h"
|
||||||
#include "core/libraries/kernel/libkernel.h"
|
#include "core/libraries/kernel/libkernel.h"
|
||||||
#include "core/libraries/libc_internal/libc_internal.h"
|
#include "core/libraries/libc_internal/libc_internal.h"
|
||||||
@ -77,6 +78,7 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
|
|||||||
Libraries::ImeDialog::RegisterlibSceImeDialog(sym);
|
Libraries::ImeDialog::RegisterlibSceImeDialog(sym);
|
||||||
Libraries::AvPlayer::RegisterlibSceAvPlayer(sym);
|
Libraries::AvPlayer::RegisterlibSceAvPlayer(sym);
|
||||||
Libraries::Audio3d::RegisterlibSceAudio3d(sym);
|
Libraries::Audio3d::RegisterlibSceAudio3d(sym);
|
||||||
|
Libraries::Fiber::RegisterlibSceFiber(sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Libraries
|
} // namespace Libraries
|
||||||
|
@ -902,12 +902,13 @@ int PS4_SYSV_ABI sceNpCreateAsyncRequest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNpCreateRequest() {
|
int PS4_SYSV_ABI sceNpCreateRequest() {
|
||||||
LOG_ERROR(Lib_NpManager, "(STUBBED) called");
|
LOG_ERROR(Lib_NpManager, "(DUMMY) called");
|
||||||
return ORBIS_OK;
|
static int id = 0;
|
||||||
|
return ++id;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNpDeleteRequest() {
|
int PS4_SYSV_ABI sceNpDeleteRequest(int reqId) {
|
||||||
LOG_ERROR(Lib_NpManager, "(STUBBED) called");
|
LOG_ERROR(Lib_NpManager, "(DUMMY) called reqId = {}", reqId);
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ int PS4_SYSV_ABI sceNpCheckNpReachability();
|
|||||||
int PS4_SYSV_ABI sceNpCheckPlus();
|
int PS4_SYSV_ABI sceNpCheckPlus();
|
||||||
int PS4_SYSV_ABI sceNpCreateAsyncRequest();
|
int PS4_SYSV_ABI sceNpCreateAsyncRequest();
|
||||||
int PS4_SYSV_ABI sceNpCreateRequest();
|
int PS4_SYSV_ABI sceNpCreateRequest();
|
||||||
int PS4_SYSV_ABI sceNpDeleteRequest();
|
int PS4_SYSV_ABI sceNpDeleteRequest(int reqId);
|
||||||
int PS4_SYSV_ABI sceNpGetAccountAge();
|
int PS4_SYSV_ABI sceNpGetAccountAge();
|
||||||
int PS4_SYSV_ABI sceNpGetAccountCountry();
|
int PS4_SYSV_ABI sceNpGetAccountCountry();
|
||||||
int PS4_SYSV_ABI sceNpGetAccountCountryA();
|
int PS4_SYSV_ABI sceNpGetAccountCountryA();
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "core/file_format/trp.h"
|
#include "core/file_format/trp.h"
|
||||||
#include "core/file_sys/fs.h"
|
#include "core/file_sys/fs.h"
|
||||||
#include "core/libraries/disc_map/disc_map.h"
|
#include "core/libraries/disc_map/disc_map.h"
|
||||||
|
#include "core/libraries/fiber/fiber.h"
|
||||||
#include "core/libraries/kernel/thread_management.h"
|
#include "core/libraries/kernel/thread_management.h"
|
||||||
#include "core/libraries/libc_internal/libc_internal.h"
|
#include "core/libraries/libc_internal/libc_internal.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
@ -258,7 +259,7 @@ void Emulator::Run(const std::filesystem::path& file) {
|
|||||||
void Emulator::LoadSystemModules(const std::filesystem::path& file) {
|
void Emulator::LoadSystemModules(const std::filesystem::path& file) {
|
||||||
constexpr std::array<SysModules, 13> ModulesToLoad{
|
constexpr std::array<SysModules, 13> ModulesToLoad{
|
||||||
{{"libSceNgs2.sprx", &Libraries::Ngs2::RegisterlibSceNgs2},
|
{{"libSceNgs2.sprx", &Libraries::Ngs2::RegisterlibSceNgs2},
|
||||||
{"libSceFiber.sprx", nullptr},
|
{"libSceFiber.sprx", &Libraries::Fiber::RegisterlibSceFiber},
|
||||||
{"libSceUlt.sprx", nullptr},
|
{"libSceUlt.sprx", nullptr},
|
||||||
{"libSceJson.sprx", nullptr},
|
{"libSceJson.sprx", nullptr},
|
||||||
{"libSceJson2.sprx", nullptr},
|
{"libSceJson2.sprx", nullptr},
|
||||||
|
@ -47,8 +47,6 @@ QStringList languageNames = {"Arabic",
|
|||||||
const QVector<int> languageIndexes = {21, 23, 14, 6, 18, 1, 12, 22, 2, 4, 25, 24, 29, 5, 0,
|
const QVector<int> languageIndexes = {21, 23, 14, 6, 18, 1, 12, 22, 2, 4, 25, 24, 29, 5, 0,
|
||||||
9, 15, 16, 17, 7, 26, 8, 11, 20, 3, 13, 27, 10, 19, 28};
|
9, 15, 16, 17, 7, 26, 8, 11, 20, 3, 13, 27, 10, 19, 28};
|
||||||
|
|
||||||
QStringList hideCursorStates = {"Never", "Idle", "Always"};
|
|
||||||
|
|
||||||
SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidget* parent)
|
SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidget* parent)
|
||||||
: QDialog(parent), ui(new Ui::SettingsDialog) {
|
: QDialog(parent), ui(new Ui::SettingsDialog) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
@ -69,7 +67,14 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
|
|||||||
completer->setCaseSensitivity(Qt::CaseInsensitive);
|
completer->setCaseSensitivity(Qt::CaseInsensitive);
|
||||||
ui->consoleLanguageComboBox->setCompleter(completer);
|
ui->consoleLanguageComboBox->setCompleter(completer);
|
||||||
|
|
||||||
ui->hideCursorComboBox->addItems(hideCursorStates);
|
ui->hideCursorComboBox->addItem(tr("Never"));
|
||||||
|
ui->hideCursorComboBox->addItem(tr("Idle"));
|
||||||
|
ui->hideCursorComboBox->addItem(tr("Always"));
|
||||||
|
|
||||||
|
ui->backButtonBehaviorComboBox->addItem(tr("Touchpad Left"), "left");
|
||||||
|
ui->backButtonBehaviorComboBox->addItem(tr("Touchpad Center"), "center");
|
||||||
|
ui->backButtonBehaviorComboBox->addItem(tr("Touchpad Right"), "right");
|
||||||
|
ui->backButtonBehaviorComboBox->addItem(tr("None"), "none");
|
||||||
|
|
||||||
InitializeEmulatorLanguages();
|
InitializeEmulatorLanguages();
|
||||||
LoadValuesFromConfig();
|
LoadValuesFromConfig();
|
||||||
@ -102,15 +107,6 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
|
|||||||
ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)->setText(tr("Restore Defaults"));
|
ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)->setText(tr("Restore Defaults"));
|
||||||
ui->buttonBox->button(QDialogButtonBox::Close)->setText(tr("Close"));
|
ui->buttonBox->button(QDialogButtonBox::Close)->setText(tr("Close"));
|
||||||
|
|
||||||
ui->backButtonBehaviorComboBox->addItem(tr("Touchpad Left"), "left");
|
|
||||||
ui->backButtonBehaviorComboBox->addItem(tr("Touchpad Center"), "center");
|
|
||||||
ui->backButtonBehaviorComboBox->addItem(tr("Touchpad Right"), "right");
|
|
||||||
ui->backButtonBehaviorComboBox->addItem(tr("None"), "none");
|
|
||||||
|
|
||||||
QString currentBackButtonBehavior = QString::fromStdString(Config::getBackButtonBehavior());
|
|
||||||
int index = ui->backButtonBehaviorComboBox->findData(currentBackButtonBehavior);
|
|
||||||
ui->backButtonBehaviorComboBox->setCurrentIndex(index != -1 ? index : 0);
|
|
||||||
|
|
||||||
connect(ui->tabWidgetSettings, &QTabWidget::currentChanged, this,
|
connect(ui->tabWidgetSettings, &QTabWidget::currentChanged, this,
|
||||||
[this]() { ui->buttonBox->button(QDialogButtonBox::Close)->setFocus(); });
|
[this]() { ui->buttonBox->button(QDialogButtonBox::Close)->setFocus(); });
|
||||||
|
|
||||||
@ -175,14 +171,6 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
|
|||||||
rpc->shutdown();
|
rpc->shutdown();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(ui->backButtonBehaviorComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
|
||||||
this, [this](int index) {
|
|
||||||
if (index >= 0 && index < ui->backButtonBehaviorComboBox->count()) {
|
|
||||||
QString data = ui->backButtonBehaviorComboBox->itemData(index).toString();
|
|
||||||
Config::setBackButtonBehavior(data.toStdString());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input TAB
|
// Input TAB
|
||||||
@ -195,6 +183,14 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
|
|||||||
|
|
||||||
connect(ui->idleTimeoutSpinBox, &QSpinBox::valueChanged, this,
|
connect(ui->idleTimeoutSpinBox, &QSpinBox::valueChanged, this,
|
||||||
[](int index) { Config::setCursorHideTimeout(index); });
|
[](int index) { Config::setCursorHideTimeout(index); });
|
||||||
|
|
||||||
|
connect(ui->backButtonBehaviorComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||||
|
this, [this](int index) {
|
||||||
|
if (index >= 0 && index < ui->backButtonBehaviorComboBox->count()) {
|
||||||
|
QString data = ui->backButtonBehaviorComboBox->itemData(index).toString();
|
||||||
|
Config::setBackButtonBehavior(data.toStdString());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// GPU TAB
|
// GPU TAB
|
||||||
@ -222,16 +218,10 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
|
|||||||
|
|
||||||
// PATH TAB
|
// PATH TAB
|
||||||
{
|
{
|
||||||
for (const auto& dir : Config::getGameInstallDirs()) {
|
|
||||||
QString path_string;
|
|
||||||
Common::FS::PathToQString(path_string, dir);
|
|
||||||
QListWidgetItem* item = new QListWidgetItem(path_string);
|
|
||||||
ui->gameFoldersListWidget->addItem(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
ui->removeFolderButton->setEnabled(false);
|
ui->removeFolderButton->setEnabled(false);
|
||||||
|
|
||||||
connect(ui->addFolderButton, &QPushButton::clicked, this, [this]() {
|
connect(ui->addFolderButton, &QPushButton::clicked, this, [this]() {
|
||||||
|
const auto config_dir = Config::getGameInstallDirs();
|
||||||
QString file_path_string =
|
QString file_path_string =
|
||||||
QFileDialog::getExistingDirectory(this, tr("Directory to install games"));
|
QFileDialog::getExistingDirectory(this, tr("Directory to install games"));
|
||||||
auto file_path = Common::FS::PathFromQString(file_path_string);
|
auto file_path = Common::FS::PathFromQString(file_path_string);
|
||||||
@ -288,6 +278,11 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
|
|||||||
ui->logFilter->installEventFilter(this);
|
ui->logFilter->installEventFilter(this);
|
||||||
ui->updaterGroupBox->installEventFilter(this);
|
ui->updaterGroupBox->installEventFilter(this);
|
||||||
ui->GUIgroupBox->installEventFilter(this);
|
ui->GUIgroupBox->installEventFilter(this);
|
||||||
|
|
||||||
|
// Input
|
||||||
|
ui->cursorGroupBox->installEventFilter(this);
|
||||||
|
ui->hideCursorGroupBox->installEventFilter(this);
|
||||||
|
ui->idleTimeoutGroupBox->installEventFilter(this);
|
||||||
ui->backButtonBehaviorGroupBox->installEventFilter(this);
|
ui->backButtonBehaviorGroupBox->installEventFilter(this);
|
||||||
|
|
||||||
// Graphics
|
// Graphics
|
||||||
@ -298,6 +293,12 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
|
|||||||
ui->dumpShadersCheckBox->installEventFilter(this);
|
ui->dumpShadersCheckBox->installEventFilter(this);
|
||||||
ui->nullGpuCheckBox->installEventFilter(this);
|
ui->nullGpuCheckBox->installEventFilter(this);
|
||||||
|
|
||||||
|
// Paths
|
||||||
|
ui->gameFoldersGroupBox->installEventFilter(this);
|
||||||
|
ui->gameFoldersListWidget->installEventFilter(this);
|
||||||
|
ui->addFolderButton->installEventFilter(this);
|
||||||
|
ui->removeFolderButton->installEventFilter(this);
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
ui->debugDump->installEventFilter(this);
|
ui->debugDump->installEventFilter(this);
|
||||||
ui->vkValidationCheckBox->installEventFilter(this);
|
ui->vkValidationCheckBox->installEventFilter(this);
|
||||||
@ -348,6 +349,13 @@ void SettingsDialog::LoadValuesFromConfig() {
|
|||||||
}
|
}
|
||||||
ui->updateComboBox->setCurrentText(QString::fromStdString(updateChannel));
|
ui->updateComboBox->setCurrentText(QString::fromStdString(updateChannel));
|
||||||
|
|
||||||
|
for (const auto& dir : Config::getGameInstallDirs()) {
|
||||||
|
QString path_string;
|
||||||
|
Common::FS::PathToQString(path_string, dir);
|
||||||
|
QListWidgetItem* item = new QListWidgetItem(path_string);
|
||||||
|
ui->gameFoldersListWidget->addItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
QString backButtonBehavior = QString::fromStdString(Config::getBackButtonBehavior());
|
QString backButtonBehavior = QString::fromStdString(Config::getBackButtonBehavior());
|
||||||
int index = ui->backButtonBehaviorComboBox->findData(backButtonBehavior);
|
int index = ui->backButtonBehaviorComboBox->findData(backButtonBehavior);
|
||||||
ui->backButtonBehaviorComboBox->setCurrentIndex(index != -1 ? index : 0);
|
ui->backButtonBehaviorComboBox->setCurrentIndex(index != -1 ? index : 0);
|
||||||
@ -424,6 +432,15 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) {
|
|||||||
text = tr("updaterGroupBox");
|
text = tr("updaterGroupBox");
|
||||||
} else if (elementName == "GUIgroupBox") {
|
} else if (elementName == "GUIgroupBox") {
|
||||||
text = tr("GUIgroupBox");
|
text = tr("GUIgroupBox");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input
|
||||||
|
if (elementName == "cursorGroupBox") {
|
||||||
|
text = tr("cursorGroupBox");
|
||||||
|
} else if (elementName == "hideCursorGroupBox") {
|
||||||
|
text = tr("hideCursorGroupBox");
|
||||||
|
} else if (elementName == "idleTimeoutGroupBox") {
|
||||||
|
text = tr("idleTimeoutGroupBox");
|
||||||
} else if (elementName == "backButtonBehaviorGroupBox") {
|
} else if (elementName == "backButtonBehaviorGroupBox") {
|
||||||
text = tr("backButtonBehaviorGroupBox");
|
text = tr("backButtonBehaviorGroupBox");
|
||||||
}
|
}
|
||||||
@ -443,6 +460,15 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) {
|
|||||||
text = tr("nullGpuCheckBox");
|
text = tr("nullGpuCheckBox");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Path
|
||||||
|
if (elementName == "gameFoldersGroupBox" || elementName == "gameFoldersListWidget") {
|
||||||
|
text = tr("gameFoldersBox");
|
||||||
|
} else if (elementName == "addFolderButton") {
|
||||||
|
text = tr("addFolderButton");
|
||||||
|
} else if (elementName == "removeFolderButton") {
|
||||||
|
text = tr("removeFolderButton");
|
||||||
|
}
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
if (elementName == "debugDump") {
|
if (elementName == "debugDump") {
|
||||||
text = tr("debugDump");
|
text = tr("debugDump");
|
||||||
|
@ -274,6 +274,9 @@
|
|||||||
<layout class="QHBoxLayout" name="generalTabHLayout_2">
|
<layout class="QHBoxLayout" name="generalTabHLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="updaterTabLayoutLeft">
|
<layout class="QVBoxLayout" name="updaterTabLayoutLeft">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SizeConstraint::SetDefaultConstraint</enum>
|
||||||
|
</property>
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
@ -286,56 +289,88 @@
|
|||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item alignment="Qt::AlignmentFlag::AlignTop">
|
||||||
<widget class="QGroupBox" name="updaterGroupBox">
|
<widget class="QGroupBox" name="updaterGroupBox">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>265</width>
|
<width>275</width>
|
||||||
<height>0</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Update</string>
|
<string>Update</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QCheckBox" name="updateCheckBox">
|
<layout class="QVBoxLayout" name="UpdateLayout" stretch="0,0,0">
|
||||||
<property name="geometry">
|
<property name="spacing">
|
||||||
<rect>
|
<number>5</number>
|
||||||
<x>10</x>
|
|
||||||
<y>130</y>
|
|
||||||
<width>261</width>
|
|
||||||
<height>22</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="topMargin">
|
||||||
<string>Check for Updates at Startup</string>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="rightMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
<widget class="QGroupBox" name="updaterComboBox">
|
<widget class="QGroupBox" name="updaterComboBox">
|
||||||
<property name="geometry">
|
<property name="sizePolicy">
|
||||||
<rect>
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
<x>12</x>
|
<horstretch>0</horstretch>
|
||||||
<y>30</y>
|
<verstretch>0</verstretch>
|
||||||
<width>241</width>
|
</sizepolicy>
|
||||||
<height>65</height>
|
</property>
|
||||||
</rect>
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>75</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Update Channel</string>
|
<string>Update Channel</string>
|
||||||
</property>
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="UpdateChannelLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
<widget class="QComboBox" name="updateComboBox">
|
<widget class="QComboBox" name="updateComboBox">
|
||||||
<property name="geometry">
|
<property name="sizePolicy">
|
||||||
<rect>
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
<x>12</x>
|
<horstretch>0</horstretch>
|
||||||
<y>30</y>
|
<verstretch>0</verstretch>
|
||||||
<width>217</width>
|
</sizepolicy>
|
||||||
<height>28</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -348,47 +383,93 @@
|
|||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
<widget class="QPushButton" name="checkUpdateButton">
|
<widget class="QPushButton" name="checkUpdateButton">
|
||||||
<property name="geometry">
|
<property name="sizePolicy">
|
||||||
<rect>
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
<x>25</x>
|
<horstretch>0</horstretch>
|
||||||
<y>100</y>
|
<verstretch>0</verstretch>
|
||||||
<width>215</width>
|
</sizepolicy>
|
||||||
<height>24</height>
|
</property>
|
||||||
</rect>
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>197</width>
|
||||||
|
<height>28</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Check for Updates</string>
|
<string>Check for Updates</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="updateCheckBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>11</pointsize>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Check for Updates at Startup</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="GUITabLayoutMiddle" stretch="1">
|
<layout class="QVBoxLayout" name="GUITabLayoutMiddle" stretch="0">
|
||||||
<item>
|
<item alignment="Qt::AlignmentFlag::AlignTop">
|
||||||
<widget class="QGroupBox" name="GUIgroupBox">
|
<widget class="QGroupBox" name="GUIgroupBox">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>GUI Settings</string>
|
<string>GUI Settings</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="verticalLayoutWidget_3">
|
<layout class="QVBoxLayout" name="GUILayout">
|
||||||
<property name="geometry">
|
<property name="topMargin">
|
||||||
<rect>
|
<number>1</number>
|
||||||
<x>10</x>
|
</property>
|
||||||
<y>30</y>
|
<property name="bottomMargin">
|
||||||
<width>241</width>
|
<number>11</number>
|
||||||
<height>92</height>
|
</property>
|
||||||
</rect>
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="GUIMusicLayout">
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="playBGMCheckBox">
|
<widget class="QCheckBox" name="playBGMCheckBox">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -403,11 +484,35 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<spacer name="GUIverticalSpacer_2">
|
||||||
<item>
|
<property name="orientation">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<enum>Qt::Orientation::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Policy::Fixed</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>2</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Volume</string>
|
<string>Volume</string>
|
||||||
</property>
|
</property>
|
||||||
@ -449,51 +554,35 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
<item>
|
||||||
|
<widget class="QWidget" name="GUIwidgetSpacer" native="true">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>61</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="ControllerTabLayoutRight" stretch="1">
|
<layout class="QVBoxLayout" name="EmptyTabLayoutRight">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="ControllerGroupBox">
|
<spacer name="emptyHorizontalSpacer">
|
||||||
<property name="sizePolicy">
|
<property name="orientation">
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
<enum>Qt::Orientation::Horizontal</enum>
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="title">
|
<property name="sizeHint" stdset="0">
|
||||||
<string>Controller Settings</string>
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QGroupBox" name="backButtonBehaviorGroupBox">
|
</spacer>
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>12</x>
|
|
||||||
<y>30</y>
|
|
||||||
<width>241</width>
|
|
||||||
<height>65</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="title">
|
|
||||||
<string>Back Button Behavior</string>
|
|
||||||
</property>
|
|
||||||
<widget class="QComboBox" name="backButtonBehaviorComboBox">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>12</x>
|
|
||||||
<y>30</y>
|
|
||||||
<width>217</width>
|
|
||||||
<height>28</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
@ -510,18 +599,48 @@
|
|||||||
<layout class="QHBoxLayout" name="inputTabHLayoutTop" stretch="1,1,1">
|
<layout class="QHBoxLayout" name="inputTabHLayoutTop" stretch="1,1,1">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="cursorTabLayoutLeft">
|
<layout class="QVBoxLayout" name="cursorTabLayoutLeft">
|
||||||
<item>
|
<property name="spacing">
|
||||||
<widget class="QGroupBox" name="HideCursor">
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item alignment="Qt::AlignmentFlag::AlignTop">
|
||||||
|
<widget class="QGroupBox" name="cursorGroupBox">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Cursor</string>
|
<string>Cursor</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="inputCursorLayout">
|
<layout class="QVBoxLayout" name="inputCursorLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="hideCursorGroupBox">
|
<widget class="QGroupBox" name="hideCursorGroupBox">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Hide Cursor</string>
|
<string>Hide Cursor</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="hideCursorLayout">
|
<layout class="QVBoxLayout" name="hideCursorLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="hideCursorComboBox"/>
|
<widget class="QComboBox" name="hideCursorComboBox"/>
|
||||||
</item>
|
</item>
|
||||||
@ -533,10 +652,16 @@
|
|||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>0</width>
|
<width>0</width>
|
||||||
<height>85</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
@ -549,19 +674,28 @@
|
|||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="IdleTimeoutLayout" stretch="0,0">
|
<layout class="QHBoxLayout" name="IdleTimeoutLayout" stretch="0,0">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>70</number>
|
<number>70</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="topMargin">
|
<property name="topMargin">
|
||||||
<number>11</number>
|
<number>5</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<property name="rightMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<item alignment="Qt::AlignmentFlag::AlignHCenter">
|
||||||
<widget class="QSpinBox" name="idleTimeoutSpinBox">
|
<widget class="QSpinBox" name="idleTimeoutSpinBox">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
@ -620,26 +754,80 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="emptyTabLayoutMiddle">
|
<layout class="QVBoxLayout" name="ControllerTabLayoutMiddle">
|
||||||
<item>
|
<item>
|
||||||
<spacer name="emptyHorizontalSpacerMiddle">
|
<widget class="QGroupBox" name="ControllerGroupBox">
|
||||||
<property name="orientation">
|
<property name="sizePolicy">
|
||||||
<enum>Qt::Orientation::Horizontal</enum>
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
<property name="title">
|
||||||
|
<string>Controller</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="ControllerLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="backButtonBehaviorGroupBox">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>40</width>
|
<width>237</width>
|
||||||
<height>20</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
<property name="title">
|
||||||
|
<string>Back Button Behavior</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="BackButtonLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="backButtonBehaviorComboBox"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="controllerWidgetSpacer" native="true">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="emptyTabLayoutRight">
|
<layout class="QVBoxLayout" name="emptyTabLayoutRight">
|
||||||
<item>
|
<item>
|
||||||
<spacer name="emptyHorizontalSpacerRight">
|
<spacer name="emptyhorizontalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Orientation::Horizontal</enum>
|
<enum>Qt::Orientation::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
|
@ -434,6 +434,41 @@
|
|||||||
<source>Log Filter</source>
|
<source>Log Filter</source>
|
||||||
<translation>Log Filter</translation>
|
<translation>Log Filter</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.ui" line="595"/>
|
||||||
|
<source>Input</source>
|
||||||
|
<translation>Input</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.ui" line="611"/>
|
||||||
|
<source>Cursor</source>
|
||||||
|
<translation>Cursor</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.ui" line="635"/>
|
||||||
|
<source>Hide Cursor</source>
|
||||||
|
<translation>Hide Cursor</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.ui" line="668"/>
|
||||||
|
<source>Hide Cursor Idle Timeout</source>
|
||||||
|
<translation>Hide Cursor Idle Timeout</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.ui" line="595"/>
|
||||||
|
<source>Input</source>
|
||||||
|
<translation>Input</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.ui" line="767"/>
|
||||||
|
<source>Controller</source>
|
||||||
|
<translation>Controller</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.ui" line="797"/>
|
||||||
|
<source>Back Button Behavior</source>
|
||||||
|
<translation>Back Button Behavior</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../settings_dialog.ui" line="272"/>
|
<location filename="../settings_dialog.ui" line="272"/>
|
||||||
<source>Graphics</source>
|
<source>Graphics</source>
|
||||||
@ -534,16 +569,6 @@
|
|||||||
<source>Volume</source>
|
<source>Volume</source>
|
||||||
<translation>Volume</translation>
|
<translation>Volume</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../settings_dialog.ui" line="455"/>
|
|
||||||
<source>Controller Settings</source>
|
|
||||||
<translation>Controller Settings</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../settings_dialog.ui" line="467"/>
|
|
||||||
<source>Back Button Behavior</source>
|
|
||||||
<translation>Back Button Behavior</translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>MainWindow</name>
|
<name>MainWindow</name>
|
||||||
@ -1033,6 +1058,41 @@
|
|||||||
<source>GUIgroupBox</source>
|
<source>GUIgroupBox</source>
|
||||||
<translation>Play Title Music:\nIf a game supports it, enable playing special music when selecting the game in the GUI.</translation>
|
<translation>Play Title Music:\nIf a game supports it, enable playing special music when selecting the game in the GUI.</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.cpp" line="392"/>
|
||||||
|
<source>cursorGroupBox</source>
|
||||||
|
<translation>Cursor:\nChange settings related to the cursor.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.cpp" line="394"/>
|
||||||
|
<source>hideCursorGroupBox</source>
|
||||||
|
<translation>Hide Cursor:\nSet cursor hiding behavior.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.cpp" line="396"/>
|
||||||
|
<source>idleTimeoutGroupBox</source>
|
||||||
|
<translation>Hide Idle Cursor Timeout:\nThe duration (seconds) after which the cursor that has been idle hides itself.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.cpp" line="70"/>
|
||||||
|
<source>Never</source>
|
||||||
|
<translation>Never</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.cpp" line="71"/>
|
||||||
|
<source>Idle</source>
|
||||||
|
<translation>Idle</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.cpp" line="72"/>
|
||||||
|
<source>Always</source>
|
||||||
|
<translation>Always</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.cpp" line="330"/>
|
||||||
|
<source>backButtonBehaviorGroupBox</source>
|
||||||
|
<translation>Back Button Behavior:\nAllows setting which part of the touchpad the back button will emulate a touch on.</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../settings_dialog.cpp" line="330"/>
|
<location filename="../settings_dialog.cpp" line="330"/>
|
||||||
<source>backButtonBehaviorGroupBox</source>
|
<source>backButtonBehaviorGroupBox</source>
|
||||||
@ -1083,6 +1143,21 @@
|
|||||||
<source>nullGpuCheckBox</source>
|
<source>nullGpuCheckBox</source>
|
||||||
<translation>Enable Null GPU:\nFor the sake of technical debugging, disables game rendering as if there were no graphics card.</translation>
|
<translation>Enable Null GPU:\nFor the sake of technical debugging, disables game rendering as if there were no graphics card.</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.cpp" line="465"/>
|
||||||
|
<source>gameFoldersBox</source>
|
||||||
|
<translation>Game Folders: The list of folders to check for installed games.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.cpp" line="465"/>
|
||||||
|
<source>addFolderButton</source>
|
||||||
|
<translation>Add: Add a folder to the list.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../settings_dialog.cpp" line="465"/>
|
||||||
|
<source>removeFolderButton</source>
|
||||||
|
<translation>Remove: Remove a folder from the list.</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../settings_dialog.cpp" line="329"/>
|
<location filename="../settings_dialog.cpp" line="329"/>
|
||||||
<source>debugDump</source>
|
<source>debugDump</source>
|
||||||
|
@ -206,10 +206,7 @@ Id DefineMain(EmitContext& ctx, const IR::Program& program) {
|
|||||||
return main;
|
return main;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) {
|
void SetupCapabilities(const Info& info, EmitContext& ctx) {
|
||||||
const auto& info = program.info;
|
|
||||||
const std::span interfaces(ctx.interfaces.data(), ctx.interfaces.size());
|
|
||||||
spv::ExecutionModel execution_model{};
|
|
||||||
ctx.AddCapability(spv::Capability::Image1D);
|
ctx.AddCapability(spv::Capability::Image1D);
|
||||||
ctx.AddCapability(spv::Capability::Sampled1D);
|
ctx.AddCapability(spv::Capability::Sampled1D);
|
||||||
ctx.AddCapability(spv::Capability::ImageQuery);
|
ctx.AddCapability(spv::Capability::ImageQuery);
|
||||||
@ -247,6 +244,19 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) {
|
|||||||
if (info.uses_group_ballot) {
|
if (info.uses_group_ballot) {
|
||||||
ctx.AddCapability(spv::Capability::GroupNonUniformBallot);
|
ctx.AddCapability(spv::Capability::GroupNonUniformBallot);
|
||||||
}
|
}
|
||||||
|
if (info.stage == Stage::Export || info.stage == Stage::Vertex) {
|
||||||
|
ctx.AddExtension("SPV_KHR_shader_draw_parameters");
|
||||||
|
ctx.AddCapability(spv::Capability::DrawParameters);
|
||||||
|
}
|
||||||
|
if (info.stage == Stage::Geometry) {
|
||||||
|
ctx.AddCapability(spv::Capability::Geometry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) {
|
||||||
|
const auto& info = program.info;
|
||||||
|
const std::span interfaces(ctx.interfaces.data(), ctx.interfaces.size());
|
||||||
|
spv::ExecutionModel execution_model{};
|
||||||
switch (program.info.stage) {
|
switch (program.info.stage) {
|
||||||
case Stage::Compute: {
|
case Stage::Compute: {
|
||||||
const std::array<u32, 3> workgroup_size{ctx.runtime_info.cs_info.workgroup_size};
|
const std::array<u32, 3> workgroup_size{ctx.runtime_info.cs_info.workgroup_size};
|
||||||
@ -290,6 +300,24 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) {
|
|||||||
ctx.AddEntryPoint(execution_model, main, "main", interfaces);
|
ctx.AddEntryPoint(execution_model, main, "main", interfaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetupFloatMode(EmitContext& ctx, const Profile& profile, const RuntimeInfo& runtime_info,
|
||||||
|
Id main_func) {
|
||||||
|
ctx.AddExtension("SPV_KHR_float_controls");
|
||||||
|
const auto fp_denorm_mode = runtime_info.fp_denorm_mode32;
|
||||||
|
if (fp_denorm_mode == AmdGpu::FpDenormMode::InOutFlush) {
|
||||||
|
if (profile.support_fp32_denorm_flush) {
|
||||||
|
ctx.AddCapability(spv::Capability::DenormFlushToZero);
|
||||||
|
ctx.AddExecutionMode(main_func, spv::ExecutionMode::DenormFlushToZero, 32U);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG_WARNING(Render_Vulkan, "Unknown FP denorm mode {}", u32(fp_denorm_mode));
|
||||||
|
}
|
||||||
|
const auto fp_round_mode = runtime_info.fp_round_mode32;
|
||||||
|
if (fp_round_mode != AmdGpu::FpRoundMode::NearestEven) {
|
||||||
|
LOG_WARNING(Render_Vulkan, "Unknown FP rounding mode {}", u32(fp_round_mode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PatchPhiNodes(const IR::Program& program, EmitContext& ctx) {
|
void PatchPhiNodes(const IR::Program& program, EmitContext& ctx) {
|
||||||
auto inst{program.blocks.front()->begin()};
|
auto inst{program.blocks.front()->begin()};
|
||||||
size_t block_index{0};
|
size_t block_index{0};
|
||||||
@ -314,18 +342,8 @@ std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_in
|
|||||||
EmitContext ctx{profile, runtime_info, program.info, binding};
|
EmitContext ctx{profile, runtime_info, program.info, binding};
|
||||||
const Id main{DefineMain(ctx, program)};
|
const Id main{DefineMain(ctx, program)};
|
||||||
DefineEntryPoint(program, ctx, main);
|
DefineEntryPoint(program, ctx, main);
|
||||||
switch (program.info.stage) {
|
SetupCapabilities(program.info, ctx);
|
||||||
case Stage::Export:
|
SetupFloatMode(ctx, profile, runtime_info, main);
|
||||||
case Stage::Vertex:
|
|
||||||
ctx.AddExtension("SPV_KHR_shader_draw_parameters");
|
|
||||||
ctx.AddCapability(spv::Capability::DrawParameters);
|
|
||||||
break;
|
|
||||||
case Stage::Geometry:
|
|
||||||
ctx.AddCapability(spv::Capability::Geometry);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
PatchPhiNodes(program, ctx);
|
PatchPhiNodes(program, ctx);
|
||||||
binding.user_data += program.info.ud_mask.NumRegs();
|
binding.user_data += program.info.ud_mask.NumRegs();
|
||||||
return ctx.Assemble();
|
return ctx.Assemble();
|
||||||
|
@ -284,7 +284,8 @@ void EmitContext::DefineInputs() {
|
|||||||
frag_coord = DefineVariable(F32[4], spv::BuiltIn::FragCoord, spv::StorageClass::Input);
|
frag_coord = DefineVariable(F32[4], spv::BuiltIn::FragCoord, spv::StorageClass::Input);
|
||||||
frag_depth = DefineVariable(F32[1], spv::BuiltIn::FragDepth, spv::StorageClass::Output);
|
frag_depth = DefineVariable(F32[1], spv::BuiltIn::FragDepth, spv::StorageClass::Output);
|
||||||
front_facing = DefineVariable(U1[1], spv::BuiltIn::FrontFacing, spv::StorageClass::Input);
|
front_facing = DefineVariable(U1[1], spv::BuiltIn::FrontFacing, spv::StorageClass::Input);
|
||||||
for (const auto& input : runtime_info.fs_info.inputs) {
|
for (s32 i = 0; i < runtime_info.fs_info.num_inputs; i++) {
|
||||||
|
const auto& input = runtime_info.fs_info.inputs[i];
|
||||||
const u32 semantic = input.param_index;
|
const u32 semantic = input.param_index;
|
||||||
ASSERT(semantic < IR::NumParams);
|
ASSERT(semantic < IR::NumParams);
|
||||||
if (input.is_default && !input.is_flat) {
|
if (input.is_default && !input.is_flat) {
|
||||||
@ -333,7 +334,6 @@ void EmitContext::DefineInputs() {
|
|||||||
|
|
||||||
const auto num_params = runtime_info.gs_info.in_vertex_data_size / 4 - 1u;
|
const auto num_params = runtime_info.gs_info.in_vertex_data_size / 4 - 1u;
|
||||||
for (int param_id = 0; param_id < num_params; ++param_id) {
|
for (int param_id = 0; param_id < num_params; ++param_id) {
|
||||||
const IR::Attribute param{IR::Attribute::Param0 + param_id};
|
|
||||||
const Id type{TypeArray(F32[4], ConstU32(num_verts_in))};
|
const Id type{TypeArray(F32[4], ConstU32(num_verts_in))};
|
||||||
const Id id{DefineInput(type, param_id)};
|
const Id id{DefineInput(type, param_id)};
|
||||||
Name(id, fmt::format("in_attr{}", param_id));
|
Name(id, fmt::format("in_attr{}", param_id));
|
||||||
@ -394,8 +394,7 @@ void EmitContext::DefineOutputs() {
|
|||||||
case Stage::Geometry: {
|
case Stage::Geometry: {
|
||||||
output_position = DefineVariable(F32[4], spv::BuiltIn::Position, spv::StorageClass::Output);
|
output_position = DefineVariable(F32[4], spv::BuiltIn::Position, spv::StorageClass::Output);
|
||||||
|
|
||||||
for (u32 attr_id = 0; attr_id < runtime_info.gs_info.copy_data.num_attrs; attr_id++) {
|
for (u32 attr_id = 0; attr_id < info.gs_copy_data.num_attrs; attr_id++) {
|
||||||
const IR::Attribute param{IR::Attribute::Param0 + attr_id};
|
|
||||||
const Id id{DefineOutput(F32[4], attr_id)};
|
const Id id{DefineOutput(F32[4], attr_id)};
|
||||||
Name(id, fmt::format("out_attr{}", attr_id));
|
Name(id, fmt::format("out_attr{}", attr_id));
|
||||||
output_params[attr_id] = {id, output_f32, F32[1], 4u};
|
output_params[attr_id] = {id, output_f32, F32[1], 4u};
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
namespace Shader {
|
namespace Shader {
|
||||||
|
|
||||||
CopyShaderData ParseCopyShader(const std::span<const u32>& code) {
|
CopyShaderData ParseCopyShader(std::span<const u32> code) {
|
||||||
Gcn::GcnCodeSlice code_slice{code.data(), code.data() + code.size()};
|
Gcn::GcnCodeSlice code_slice{code.data(), code.data() + code.size()};
|
||||||
Gcn::GcnDecodeContext decoder;
|
Gcn::GcnDecodeContext decoder;
|
||||||
|
|
||||||
|
@ -16,6 +16,6 @@ struct CopyShaderData {
|
|||||||
u32 num_attrs{0};
|
u32 num_attrs{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
CopyShaderData ParseCopyShader(const std::span<const u32>& code);
|
CopyShaderData ParseCopyShader(std::span<const u32> code);
|
||||||
|
|
||||||
} // namespace Shader
|
} // namespace Shader
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <vector>
|
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
#include <boost/container/static_vector.hpp>
|
#include <boost/container/static_vector.hpp>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
#include "shader_recompiler/backend/bindings.h"
|
#include "shader_recompiler/backend/bindings.h"
|
||||||
|
#include "shader_recompiler/frontend/copy_shader.h"
|
||||||
#include "shader_recompiler/ir/attribute.h"
|
#include "shader_recompiler/ir/attribute.h"
|
||||||
#include "shader_recompiler/ir/reg.h"
|
#include "shader_recompiler/ir/reg.h"
|
||||||
#include "shader_recompiler/ir/type.h"
|
#include "shader_recompiler/ir/type.h"
|
||||||
@ -170,6 +170,8 @@ struct Info {
|
|||||||
};
|
};
|
||||||
UserDataMask ud_mask{};
|
UserDataMask ud_mask{};
|
||||||
|
|
||||||
|
CopyShaderData gs_copy_data;
|
||||||
|
|
||||||
s8 vertex_offset_sgpr = -1;
|
s8 vertex_offset_sgpr = -1;
|
||||||
s8 instance_offset_sgpr = -1;
|
s8 instance_offset_sgpr = -1;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "shader_recompiler/frontend/translate/translate.h"
|
#include "shader_recompiler/ir/ir_emitter.h"
|
||||||
#include "shader_recompiler/ir/opcodes.h"
|
#include "shader_recompiler/ir/opcodes.h"
|
||||||
#include "shader_recompiler/ir/program.h"
|
#include "shader_recompiler/ir/program.h"
|
||||||
#include "shader_recompiler/ir/reg.h"
|
#include "shader_recompiler/ir/reg.h"
|
||||||
@ -11,6 +11,8 @@ namespace Shader::Optimization {
|
|||||||
|
|
||||||
void RingAccessElimination(const IR::Program& program, const RuntimeInfo& runtime_info,
|
void RingAccessElimination(const IR::Program& program, const RuntimeInfo& runtime_info,
|
||||||
Stage stage) {
|
Stage stage) {
|
||||||
|
auto& info = program.info;
|
||||||
|
|
||||||
const auto& ForEachInstruction = [&](auto func) {
|
const auto& ForEachInstruction = [&](auto func) {
|
||||||
for (IR::Block* block : program.blocks) {
|
for (IR::Block* block : program.blocks) {
|
||||||
for (IR::Inst& inst : block->Instructions()) {
|
for (IR::Inst& inst : block->Instructions()) {
|
||||||
@ -52,6 +54,9 @@ void RingAccessElimination(const IR::Program& program, const RuntimeInfo& runtim
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Stage::Geometry: {
|
case Stage::Geometry: {
|
||||||
|
const auto& gs_info = runtime_info.gs_info;
|
||||||
|
info.gs_copy_data = Shader::ParseCopyShader(gs_info.vs_copy);
|
||||||
|
|
||||||
ForEachInstruction([&](IR::IREmitter& ir, IR::Inst& inst) {
|
ForEachInstruction([&](IR::IREmitter& ir, IR::Inst& inst) {
|
||||||
const auto opcode = inst.GetOpcode();
|
const auto opcode = inst.GetOpcode();
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
@ -81,12 +86,12 @@ void RingAccessElimination(const IR::Program& program, const RuntimeInfo& runtim
|
|||||||
|
|
||||||
const auto offset = inst.Flags<IR::BufferInstInfo>().inst_offset.Value();
|
const auto offset = inst.Flags<IR::BufferInstInfo>().inst_offset.Value();
|
||||||
const auto data = ir.BitCast<IR::F32>(IR::U32{inst.Arg(2)});
|
const auto data = ir.BitCast<IR::F32>(IR::U32{inst.Arg(2)});
|
||||||
const auto comp_ofs = runtime_info.gs_info.output_vertices * 4u;
|
const auto comp_ofs = gs_info.output_vertices * 4u;
|
||||||
const auto output_size = comp_ofs * runtime_info.gs_info.out_vertex_data_size;
|
const auto output_size = comp_ofs * gs_info.out_vertex_data_size;
|
||||||
|
|
||||||
const auto vc_read_ofs = (((offset / comp_ofs) * comp_ofs) % output_size) * 16u;
|
const auto vc_read_ofs = (((offset / comp_ofs) * comp_ofs) % output_size) * 16u;
|
||||||
const auto& it = runtime_info.gs_info.copy_data.attr_map.find(vc_read_ofs);
|
const auto& it = info.gs_copy_data.attr_map.find(vc_read_ofs);
|
||||||
ASSERT(it != runtime_info.gs_info.copy_data.attr_map.cend());
|
ASSERT(it != info.gs_copy_data.attr_map.cend());
|
||||||
const auto& [attr, comp] = it->second;
|
const auto& [attr, comp] = it->second;
|
||||||
|
|
||||||
inst.ReplaceOpcode(IR::Opcode::SetAttribute);
|
inst.ReplaceOpcode(IR::Opcode::SetAttribute);
|
||||||
|
@ -10,20 +10,6 @@
|
|||||||
|
|
||||||
namespace Shader::IR {
|
namespace Shader::IR {
|
||||||
|
|
||||||
enum class FpRoundMode : u32 {
|
|
||||||
NearestEven = 0,
|
|
||||||
PlusInf = 1,
|
|
||||||
MinInf = 2,
|
|
||||||
ToZero = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class FpDenormMode : u32 {
|
|
||||||
InOutFlush = 0,
|
|
||||||
InAllowOutFlush = 1,
|
|
||||||
InFlushOutAllow = 2,
|
|
||||||
InOutAllow = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class FloatClassFunc : u32 {
|
enum class FloatClassFunc : u32 {
|
||||||
SignalingNan = 1 << 0,
|
SignalingNan = 1 << 0,
|
||||||
QuietNan = 1 << 1,
|
QuietNan = 1 << 1,
|
||||||
@ -41,13 +27,6 @@ enum class FloatClassFunc : u32 {
|
|||||||
};
|
};
|
||||||
DECLARE_ENUM_FLAG_OPERATORS(FloatClassFunc)
|
DECLARE_ENUM_FLAG_OPERATORS(FloatClassFunc)
|
||||||
|
|
||||||
union Mode {
|
|
||||||
BitField<0, 4, FpRoundMode> fp_round;
|
|
||||||
BitField<4, 2, FpDenormMode> fp_denorm_single;
|
|
||||||
BitField<6, 2, FpDenormMode> fp_denorm_double;
|
|
||||||
BitField<8, 1, u32> dx10_clamp;
|
|
||||||
};
|
|
||||||
|
|
||||||
union TextureInstInfo {
|
union TextureInstInfo {
|
||||||
u32 raw;
|
u32 raw;
|
||||||
BitField<0, 1, u32> is_depth;
|
BitField<0, 1, u32> is_depth;
|
||||||
|
@ -19,13 +19,8 @@ struct Profile {
|
|||||||
bool support_float_controls{};
|
bool support_float_controls{};
|
||||||
bool support_separate_denorm_behavior{};
|
bool support_separate_denorm_behavior{};
|
||||||
bool support_separate_rounding_mode{};
|
bool support_separate_rounding_mode{};
|
||||||
bool support_fp16_denorm_preserve{};
|
|
||||||
bool support_fp32_denorm_preserve{};
|
bool support_fp32_denorm_preserve{};
|
||||||
bool support_fp16_denorm_flush{};
|
|
||||||
bool support_fp32_denorm_flush{};
|
bool support_fp32_denorm_flush{};
|
||||||
bool support_fp16_signed_zero_nan_preserve{};
|
|
||||||
bool support_fp32_signed_zero_nan_preserve{};
|
|
||||||
bool support_fp64_signed_zero_nan_preserve{};
|
|
||||||
bool support_explicit_workgroup_layout{};
|
bool support_explicit_workgroup_layout{};
|
||||||
bool has_broken_spirv_clamp{};
|
bool has_broken_spirv_clamp{};
|
||||||
bool lower_left_origin_mode{};
|
bool lower_left_origin_mode{};
|
||||||
|
@ -4,11 +4,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <span>
|
||||||
#include <boost/container/static_vector.hpp>
|
#include <boost/container/static_vector.hpp>
|
||||||
|
|
||||||
#include "common/assert.h"
|
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
#include "frontend/copy_shader.h"
|
|
||||||
#include "video_core/amdgpu/types.h"
|
#include "video_core/amdgpu/types.h"
|
||||||
|
|
||||||
namespace Shader {
|
namespace Shader {
|
||||||
@ -62,7 +60,8 @@ enum class VsOutput : u8 {
|
|||||||
using VsOutputMap = std::array<VsOutput, 4>;
|
using VsOutputMap = std::array<VsOutput, 4>;
|
||||||
|
|
||||||
struct VertexRuntimeInfo {
|
struct VertexRuntimeInfo {
|
||||||
boost::container::static_vector<VsOutputMap, 3> outputs;
|
u32 num_outputs;
|
||||||
|
std::array<VsOutputMap, 3> outputs;
|
||||||
bool emulate_depth_negative_one_to_one{};
|
bool emulate_depth_negative_one_to_one{};
|
||||||
|
|
||||||
bool operator==(const VertexRuntimeInfo& other) const noexcept {
|
bool operator==(const VertexRuntimeInfo& other) const noexcept {
|
||||||
@ -79,13 +78,13 @@ struct GeometryRuntimeInfo {
|
|||||||
u32 out_vertex_data_size{};
|
u32 out_vertex_data_size{};
|
||||||
AmdGpu::PrimitiveType in_primitive;
|
AmdGpu::PrimitiveType in_primitive;
|
||||||
GsOutputPrimTypes out_primitive;
|
GsOutputPrimTypes out_primitive;
|
||||||
CopyShaderData copy_data;
|
std::span<const u32> vs_copy;
|
||||||
|
u64 vs_copy_hash;
|
||||||
|
|
||||||
bool operator==(const GeometryRuntimeInfo& other) const noexcept {
|
bool operator==(const GeometryRuntimeInfo& other) const noexcept {
|
||||||
return num_invocations && other.num_invocations &&
|
return num_invocations && other.num_invocations &&
|
||||||
output_vertices == other.output_vertices && in_primitive == other.in_primitive &&
|
output_vertices == other.output_vertices && in_primitive == other.in_primitive &&
|
||||||
std::ranges::equal(out_primitive, other.out_primitive) &&
|
std::ranges::equal(out_primitive, other.out_primitive);
|
||||||
std::ranges::equal(copy_data.attr_map, other.copy_data.attr_map);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -106,7 +105,8 @@ struct FragmentRuntimeInfo {
|
|||||||
|
|
||||||
auto operator<=>(const PsInput&) const noexcept = default;
|
auto operator<=>(const PsInput&) const noexcept = default;
|
||||||
};
|
};
|
||||||
boost::container::static_vector<PsInput, 32> inputs;
|
u32 num_inputs;
|
||||||
|
std::array<PsInput, 32> inputs;
|
||||||
struct PsColorBuffer {
|
struct PsColorBuffer {
|
||||||
AmdGpu::NumberFormat num_format;
|
AmdGpu::NumberFormat num_format;
|
||||||
MrtSwizzle mrt_swizzle;
|
MrtSwizzle mrt_swizzle;
|
||||||
@ -117,7 +117,9 @@ struct FragmentRuntimeInfo {
|
|||||||
|
|
||||||
bool operator==(const FragmentRuntimeInfo& other) const noexcept {
|
bool operator==(const FragmentRuntimeInfo& other) const noexcept {
|
||||||
return std::ranges::equal(color_buffers, other.color_buffers) &&
|
return std::ranges::equal(color_buffers, other.color_buffers) &&
|
||||||
std::ranges::equal(inputs, other.inputs);
|
num_inputs == other.num_inputs &&
|
||||||
|
std::ranges::equal(inputs.begin(), inputs.begin() + num_inputs, other.inputs.begin(),
|
||||||
|
other.inputs.begin() + num_inputs);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -141,11 +143,15 @@ struct RuntimeInfo {
|
|||||||
u32 num_user_data;
|
u32 num_user_data;
|
||||||
u32 num_input_vgprs;
|
u32 num_input_vgprs;
|
||||||
u32 num_allocated_vgprs;
|
u32 num_allocated_vgprs;
|
||||||
|
AmdGpu::FpDenormMode fp_denorm_mode32;
|
||||||
|
AmdGpu::FpRoundMode fp_round_mode32;
|
||||||
|
union {
|
||||||
ExportRuntimeInfo es_info;
|
ExportRuntimeInfo es_info;
|
||||||
VertexRuntimeInfo vs_info;
|
VertexRuntimeInfo vs_info;
|
||||||
GeometryRuntimeInfo gs_info;
|
GeometryRuntimeInfo gs_info;
|
||||||
FragmentRuntimeInfo fs_info;
|
FragmentRuntimeInfo fs_info;
|
||||||
ComputeRuntimeInfo cs_info;
|
ComputeRuntimeInfo cs_info;
|
||||||
|
};
|
||||||
|
|
||||||
RuntimeInfo(Stage stage_) : stage{stage_} {}
|
RuntimeInfo(Stage stage_) : stage{stage_} {}
|
||||||
|
|
||||||
|
@ -226,6 +226,17 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PM4CmdNop::PayloadType::DebugColorMarkerPush: {
|
||||||
|
const auto marker_sz = nop->header.count.Value() * 2;
|
||||||
|
const std::string_view label{reinterpret_cast<const char*>(&nop->data_block[1]),
|
||||||
|
marker_sz};
|
||||||
|
const u32 color = *reinterpret_cast<const u32*>(
|
||||||
|
reinterpret_cast<const u8*>(&nop->data_block[1]) + marker_sz);
|
||||||
|
if (rasterizer) {
|
||||||
|
rasterizer->ScopedMarkerInsertColor(label, color);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case PM4CmdNop::PayloadType::DebugMarkerPop: {
|
case PM4CmdNop::PayloadType::DebugMarkerPop: {
|
||||||
if (rasterizer) {
|
if (rasterizer) {
|
||||||
rasterizer->ScopeMarkerEnd();
|
rasterizer->ScopeMarkerEnd();
|
||||||
|
@ -92,6 +92,12 @@ struct Liverpool {
|
|||||||
union {
|
union {
|
||||||
BitField<0, 6, u64> num_vgprs;
|
BitField<0, 6, u64> num_vgprs;
|
||||||
BitField<6, 4, u64> num_sgprs;
|
BitField<6, 4, u64> num_sgprs;
|
||||||
|
BitField<10, 2, u64> priority;
|
||||||
|
BitField<12, 2, FpRoundMode> fp_round_mode32;
|
||||||
|
BitField<14, 2, FpRoundMode> fp_round_mode64;
|
||||||
|
BitField<16, 2, FpDenormMode> fp_denorm_mode32;
|
||||||
|
BitField<18, 2, FpDenormMode> fp_denorm_mode64;
|
||||||
|
BitField<12, 8, u64> float_mode;
|
||||||
BitField<24, 2, u64> vgpr_comp_cnt; // SPI provided per-thread inputs
|
BitField<24, 2, u64> vgpr_comp_cnt; // SPI provided per-thread inputs
|
||||||
BitField<33, 5, u64> num_user_regs;
|
BitField<33, 5, u64> num_user_regs;
|
||||||
} settings;
|
} settings;
|
||||||
|
@ -7,6 +7,20 @@
|
|||||||
|
|
||||||
namespace AmdGpu {
|
namespace AmdGpu {
|
||||||
|
|
||||||
|
enum class FpRoundMode : u32 {
|
||||||
|
NearestEven = 0,
|
||||||
|
PlusInf = 1,
|
||||||
|
MinInf = 2,
|
||||||
|
ToZero = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class FpDenormMode : u32 {
|
||||||
|
InOutFlush = 0,
|
||||||
|
InAllowOutFlush = 1,
|
||||||
|
InFlushOutAllow = 2,
|
||||||
|
InOutAllow = 3,
|
||||||
|
};
|
||||||
|
|
||||||
// See `VGT_PRIMITIVE_TYPE` description in [Radeon Sea Islands 3D/Compute Register Reference Guide]
|
// See `VGT_PRIMITIVE_TYPE` description in [Radeon Sea Islands 3D/Compute Register Reference Guide]
|
||||||
enum class PrimitiveType : u32 {
|
enum class PrimitiveType : u32 {
|
||||||
None = 0,
|
None = 0,
|
||||||
|
@ -217,9 +217,10 @@ bool Instance::CreateDevice() {
|
|||||||
const vk::StructureChain properties_chain = physical_device.getProperties2<
|
const vk::StructureChain properties_chain = physical_device.getProperties2<
|
||||||
vk::PhysicalDeviceProperties2, vk::PhysicalDevicePortabilitySubsetPropertiesKHR,
|
vk::PhysicalDeviceProperties2, vk::PhysicalDevicePortabilitySubsetPropertiesKHR,
|
||||||
vk::PhysicalDeviceExternalMemoryHostPropertiesEXT, vk::PhysicalDeviceVulkan11Properties,
|
vk::PhysicalDeviceExternalMemoryHostPropertiesEXT, vk::PhysicalDeviceVulkan11Properties,
|
||||||
vk::PhysicalDevicePushDescriptorPropertiesKHR>();
|
vk::PhysicalDevicePushDescriptorPropertiesKHR, vk::PhysicalDeviceVulkan12Properties>();
|
||||||
subgroup_size = properties_chain.get<vk::PhysicalDeviceVulkan11Properties>().subgroupSize;
|
subgroup_size = properties_chain.get<vk::PhysicalDeviceVulkan11Properties>().subgroupSize;
|
||||||
push_descriptor_props = properties_chain.get<vk::PhysicalDevicePushDescriptorPropertiesKHR>();
|
push_descriptor_props = properties_chain.get<vk::PhysicalDevicePushDescriptorPropertiesKHR>();
|
||||||
|
vk12_props = properties_chain.get<vk::PhysicalDeviceVulkan12Properties>();
|
||||||
LOG_INFO(Render_Vulkan, "Physical device subgroup size {}", subgroup_size);
|
LOG_INFO(Render_Vulkan, "Physical device subgroup size {}", subgroup_size);
|
||||||
|
|
||||||
features = feature_chain.get().features;
|
features = feature_chain.get().features;
|
||||||
|
@ -242,6 +242,11 @@ public:
|
|||||||
return push_descriptor_props.maxPushDescriptors;
|
return push_descriptor_props.maxPushDescriptors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the vulkan 1.2 physical device properties.
|
||||||
|
const vk::PhysicalDeviceVulkan12Properties& GetVk12Properties() const noexcept {
|
||||||
|
return vk12_props;
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if shaders can declare the ClipDistance attribute
|
/// Returns true if shaders can declare the ClipDistance attribute
|
||||||
bool IsShaderClipDistanceSupported() const {
|
bool IsShaderClipDistanceSupported() const {
|
||||||
return features.shaderClipDistance;
|
return features.shaderClipDistance;
|
||||||
@ -279,6 +284,7 @@ private:
|
|||||||
vk::UniqueDevice device;
|
vk::UniqueDevice device;
|
||||||
vk::PhysicalDeviceProperties properties;
|
vk::PhysicalDeviceProperties properties;
|
||||||
vk::PhysicalDevicePushDescriptorPropertiesKHR push_descriptor_props;
|
vk::PhysicalDevicePushDescriptorPropertiesKHR push_descriptor_props;
|
||||||
|
vk::PhysicalDeviceVulkan12Properties vk12_props;
|
||||||
vk::PhysicalDeviceFeatures features;
|
vk::PhysicalDeviceFeatures features;
|
||||||
vk::DriverIdKHR driver_id;
|
vk::DriverIdKHR driver_id;
|
||||||
vk::UniqueDebugUtilsMessengerEXT debug_callback{};
|
vk::UniqueDebugUtilsMessengerEXT debug_callback{};
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
#include "common/io_file.h"
|
#include "common/io_file.h"
|
||||||
#include "common/path_util.h"
|
#include "common/path_util.h"
|
||||||
#include "shader_recompiler/backend/spirv/emit_spirv.h"
|
#include "shader_recompiler/backend/spirv/emit_spirv.h"
|
||||||
#include "shader_recompiler/frontend/copy_shader.h"
|
|
||||||
#include "shader_recompiler/info.h"
|
#include "shader_recompiler/info.h"
|
||||||
#include "shader_recompiler/recompiler.h"
|
#include "shader_recompiler/recompiler.h"
|
||||||
#include "shader_recompiler/runtime_info.h"
|
#include "shader_recompiler/runtime_info.h"
|
||||||
@ -41,7 +40,7 @@ void GatherVertexOutputs(Shader::VertexRuntimeInfo& info,
|
|||||||
const auto add_output = [&](VsOutput x, VsOutput y, VsOutput z, VsOutput w) {
|
const auto add_output = [&](VsOutput x, VsOutput y, VsOutput z, VsOutput w) {
|
||||||
if (x != VsOutput::None || y != VsOutput::None || z != VsOutput::None ||
|
if (x != VsOutput::None || y != VsOutput::None || z != VsOutput::None ||
|
||||||
w != VsOutput::None) {
|
w != VsOutput::None) {
|
||||||
info.outputs.emplace_back(Shader::VsOutputMap{x, y, z, w});
|
info.outputs[info.num_outputs++] = Shader::VsOutputMap{x, y, z, w};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// VS_OUT_MISC_VEC
|
// VS_OUT_MISC_VEC
|
||||||
@ -84,18 +83,21 @@ void GatherVertexOutputs(Shader::VertexRuntimeInfo& info,
|
|||||||
Shader::RuntimeInfo PipelineCache::BuildRuntimeInfo(Shader::Stage stage) {
|
Shader::RuntimeInfo PipelineCache::BuildRuntimeInfo(Shader::Stage stage) {
|
||||||
auto info = Shader::RuntimeInfo{stage};
|
auto info = Shader::RuntimeInfo{stage};
|
||||||
const auto& regs = liverpool->regs;
|
const auto& regs = liverpool->regs;
|
||||||
|
const auto BuildCommon = [&](const auto& program) {
|
||||||
|
info.num_user_data = program.settings.num_user_regs;
|
||||||
|
info.num_input_vgprs = program.settings.vgpr_comp_cnt;
|
||||||
|
info.num_allocated_vgprs = program.settings.num_vgprs * 4;
|
||||||
|
info.fp_denorm_mode32 = program.settings.fp_denorm_mode32;
|
||||||
|
info.fp_round_mode32 = program.settings.fp_round_mode32;
|
||||||
|
};
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case Shader::Stage::Export: {
|
case Shader::Stage::Export: {
|
||||||
info.num_user_data = regs.es_program.settings.num_user_regs;
|
BuildCommon(regs.es_program);
|
||||||
info.num_input_vgprs = regs.es_program.settings.vgpr_comp_cnt;
|
|
||||||
info.num_allocated_vgprs = regs.es_program.settings.num_vgprs * 4;
|
|
||||||
info.es_info.vertex_data_size = regs.vgt_esgs_ring_itemsize;
|
info.es_info.vertex_data_size = regs.vgt_esgs_ring_itemsize;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Shader::Stage::Vertex: {
|
case Shader::Stage::Vertex: {
|
||||||
info.num_user_data = regs.vs_program.settings.num_user_regs;
|
BuildCommon(regs.vs_program);
|
||||||
info.num_input_vgprs = regs.vs_program.settings.vgpr_comp_cnt;
|
|
||||||
info.num_allocated_vgprs = regs.vs_program.settings.num_vgprs * 4;
|
|
||||||
GatherVertexOutputs(info.vs_info, regs.vs_output_control);
|
GatherVertexOutputs(info.vs_info, regs.vs_output_control);
|
||||||
info.vs_info.emulate_depth_negative_one_to_one =
|
info.vs_info.emulate_depth_negative_one_to_one =
|
||||||
!instance.IsDepthClipControlSupported() &&
|
!instance.IsDepthClipControlSupported() &&
|
||||||
@ -103,39 +105,35 @@ Shader::RuntimeInfo PipelineCache::BuildRuntimeInfo(Shader::Stage stage) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Shader::Stage::Geometry: {
|
case Shader::Stage::Geometry: {
|
||||||
info.num_user_data = regs.gs_program.settings.num_user_regs;
|
BuildCommon(regs.gs_program);
|
||||||
info.num_input_vgprs = regs.gs_program.settings.vgpr_comp_cnt;
|
auto& gs_info = info.gs_info;
|
||||||
info.num_allocated_vgprs = regs.gs_program.settings.num_vgprs * 4;
|
gs_info.output_vertices = regs.vgt_gs_max_vert_out;
|
||||||
info.gs_info.output_vertices = regs.vgt_gs_max_vert_out;
|
gs_info.num_invocations =
|
||||||
info.gs_info.num_invocations =
|
|
||||||
regs.vgt_gs_instance_cnt.IsEnabled() ? regs.vgt_gs_instance_cnt.count : 1;
|
regs.vgt_gs_instance_cnt.IsEnabled() ? regs.vgt_gs_instance_cnt.count : 1;
|
||||||
info.gs_info.in_primitive = regs.primitive_type;
|
gs_info.in_primitive = regs.primitive_type;
|
||||||
for (u32 stream_id = 0; stream_id < Shader::GsMaxOutputStreams; ++stream_id) {
|
for (u32 stream_id = 0; stream_id < Shader::GsMaxOutputStreams; ++stream_id) {
|
||||||
info.gs_info.out_primitive[stream_id] =
|
gs_info.out_primitive[stream_id] =
|
||||||
regs.vgt_gs_out_prim_type.GetPrimitiveType(stream_id);
|
regs.vgt_gs_out_prim_type.GetPrimitiveType(stream_id);
|
||||||
}
|
}
|
||||||
info.gs_info.in_vertex_data_size = regs.vgt_esgs_ring_itemsize;
|
gs_info.in_vertex_data_size = regs.vgt_esgs_ring_itemsize;
|
||||||
info.gs_info.out_vertex_data_size = regs.vgt_gs_vert_itemsize[0];
|
gs_info.out_vertex_data_size = regs.vgt_gs_vert_itemsize[0];
|
||||||
|
const auto params_vc = Liverpool::GetParams(regs.vs_program);
|
||||||
// Extract semantics offsets from a copy shader
|
gs_info.vs_copy = params_vc.code;
|
||||||
const auto vc_stage = Shader::Stage::Vertex;
|
gs_info.vs_copy_hash = params_vc.hash;
|
||||||
const auto* pgm_vc = regs.ProgramForStage(static_cast<u32>(vc_stage));
|
DumpShader(gs_info.vs_copy, gs_info.vs_copy_hash, Shader::Stage::Vertex, 0, "copy.bin");
|
||||||
const auto params_vc = Liverpool::GetParams(*pgm_vc);
|
|
||||||
DumpShader(params_vc.code, params_vc.hash, Shader::Stage::Vertex, 0, "copy.bin");
|
|
||||||
info.gs_info.copy_data = Shader::ParseCopyShader(params_vc.code);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Shader::Stage::Fragment: {
|
case Shader::Stage::Fragment: {
|
||||||
info.num_user_data = regs.ps_program.settings.num_user_regs;
|
BuildCommon(regs.ps_program);
|
||||||
info.num_allocated_vgprs = regs.ps_program.settings.num_vgprs * 4;
|
|
||||||
const auto& ps_inputs = regs.ps_inputs;
|
const auto& ps_inputs = regs.ps_inputs;
|
||||||
|
info.fs_info.num_inputs = regs.num_interp;
|
||||||
for (u32 i = 0; i < regs.num_interp; i++) {
|
for (u32 i = 0; i < regs.num_interp; i++) {
|
||||||
info.fs_info.inputs.push_back({
|
info.fs_info.inputs[i] = {
|
||||||
.param_index = u8(ps_inputs[i].input_offset.Value()),
|
.param_index = u8(ps_inputs[i].input_offset.Value()),
|
||||||
.is_default = bool(ps_inputs[i].use_default),
|
.is_default = bool(ps_inputs[i].use_default),
|
||||||
.is_flat = bool(ps_inputs[i].flat_shade),
|
.is_flat = bool(ps_inputs[i].flat_shade),
|
||||||
.default_value = u8(ps_inputs[i].default_value),
|
.default_value = u8(ps_inputs[i].default_value),
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
for (u32 i = 0; i < Shader::MaxColorBuffers; i++) {
|
for (u32 i = 0; i < Shader::MaxColorBuffers; i++) {
|
||||||
info.fs_info.color_buffers[i] = {
|
info.fs_info.color_buffers[i] = {
|
||||||
@ -166,9 +164,12 @@ PipelineCache::PipelineCache(const Instance& instance_, Scheduler& scheduler_,
|
|||||||
AmdGpu::Liverpool* liverpool_)
|
AmdGpu::Liverpool* liverpool_)
|
||||||
: instance{instance_}, scheduler{scheduler_}, liverpool{liverpool_},
|
: instance{instance_}, scheduler{scheduler_}, liverpool{liverpool_},
|
||||||
desc_heap{instance, scheduler.GetMasterSemaphore(), DescriptorHeapSizes} {
|
desc_heap{instance, scheduler.GetMasterSemaphore(), DescriptorHeapSizes} {
|
||||||
|
const auto& vk12_props = instance.GetVk12Properties();
|
||||||
profile = Shader::Profile{
|
profile = Shader::Profile{
|
||||||
.supported_spirv = instance.ApiVersion() >= VK_API_VERSION_1_3 ? 0x00010600U : 0x00010500U,
|
.supported_spirv = instance.ApiVersion() >= VK_API_VERSION_1_3 ? 0x00010600U : 0x00010500U,
|
||||||
.subgroup_size = instance.SubgroupSize(),
|
.subgroup_size = instance.SubgroupSize(),
|
||||||
|
.support_fp32_denorm_preserve = bool(vk12_props.shaderDenormPreserveFloat32),
|
||||||
|
.support_fp32_denorm_flush = bool(vk12_props.shaderDenormFlushToZeroFloat32),
|
||||||
.support_explicit_workgroup_layout = true,
|
.support_explicit_workgroup_layout = true,
|
||||||
};
|
};
|
||||||
auto [cache_result, cache] = instance.GetDevice().createPipelineCacheUnique({});
|
auto [cache_result, cache] = instance.GetDevice().createPipelineCacheUnique({});
|
||||||
|
@ -459,4 +459,17 @@ void Rasterizer::ScopedMarkerInsert(const std::string_view& str) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Rasterizer::ScopedMarkerInsertColor(const std::string_view& str, const u32 color) {
|
||||||
|
if (Config::nullGpu() || !Config::vkMarkersEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto cmdbuf = scheduler.CommandBuffer();
|
||||||
|
cmdbuf.insertDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT{
|
||||||
|
.pLabelName = str.data(),
|
||||||
|
.color = std::array<f32, 4>(
|
||||||
|
{(f32)((color >> 16) & 0xff) / 255.0f, (f32)((color >> 8) & 0xff) / 255.0f,
|
||||||
|
(f32)(color & 0xff) / 255.0f, (f32)((color >> 24) & 0xff) / 255.0f})});
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
@ -40,6 +40,7 @@ public:
|
|||||||
void ScopeMarkerBegin(const std::string_view& str);
|
void ScopeMarkerBegin(const std::string_view& str);
|
||||||
void ScopeMarkerEnd();
|
void ScopeMarkerEnd();
|
||||||
void ScopedMarkerInsert(const std::string_view& str);
|
void ScopedMarkerInsert(const std::string_view& str);
|
||||||
|
void ScopedMarkerInsertColor(const std::string_view& str, const u32 color);
|
||||||
|
|
||||||
void InlineDataToGds(u32 gds_offset, u32 value);
|
void InlineDataToGds(u32 gds_offset, u32 value);
|
||||||
u32 ReadDataFromGds(u32 gsd_offset);
|
u32 ReadDataFromGds(u32 gsd_offset);
|
||||||
|
Loading…
Reference in New Issue
Block a user