forked from MeloNX/MeloNX
Edit MoltenVK and remove "MVK: Pre-Fill Metal Command Buffers" due to not being needed anymore
This commit is contained in:
parent
f2ea6448dc
commit
cb114fbb68
@ -26,7 +26,6 @@
|
||||
/* Begin PBXBuildFile section */
|
||||
4E0DED342D05695D00FEF007 /* SwiftUIJoystick in Frameworks */ = {isa = PBXBuildFile; productRef = 4E0DED332D05695D00FEF007 /* SwiftUIJoystick */; };
|
||||
4EA5AE822D16807500AD0B9F /* SwiftSVG in Frameworks */ = {isa = PBXBuildFile; productRef = 4EA5AE812D16807500AD0B9F /* SwiftSVG */; };
|
||||
5650564B2D2A758600C8BB1E /* dotnet.xcconfig.example in Resources */ = {isa = PBXBuildFile; fileRef = 5650564A2D2A758600C8BB1E /* dotnet.xcconfig.example */; };
|
||||
CA8F9C322D3F5AB200D7E586 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E80AA622CD7122800029585 /* GameController.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@ -392,7 +391,6 @@
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
5650564B2D2A758600C8BB1E /* dotnet.xcconfig.example in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -626,6 +624,8 @@
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/MeloNX/Dependencies/XCFrameworks",
|
||||
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
|
||||
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
|
||||
);
|
||||
GCC_OPTIMIZATION_LEVEL = fast;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
@ -644,7 +644,13 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
|
||||
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
|
||||
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
|
||||
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
|
||||
);
|
||||
MARKETING_VERSION = 0.0.8;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.stossy11.MeloNX;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@ -670,6 +676,8 @@
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/MeloNX/Dependencies/XCFrameworks",
|
||||
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
|
||||
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
|
||||
);
|
||||
GCC_OPTIMIZATION_LEVEL = fast;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
@ -688,7 +696,13 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
|
||||
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
|
||||
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
|
||||
"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
|
||||
);
|
||||
MARKETING_VERSION = 0.0.8;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.stossy11.MeloNX;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
Binary file not shown.
@ -19,9 +19,9 @@ extern "C" {
|
||||
struct GameInfo {
|
||||
long FileSize;
|
||||
char TitleName[512];
|
||||
long TitleId;
|
||||
char TitleId[32];
|
||||
char Developer[256];
|
||||
int Version;
|
||||
char Version[16];
|
||||
unsigned char* ImageData;
|
||||
unsigned int ImageSize;
|
||||
};
|
||||
|
@ -33,7 +33,6 @@ func waitForController() {
|
||||
let controllerView = ControllerView()
|
||||
let newHostingController = UIHostingController(rootView: controllerView)
|
||||
|
||||
// Store reference globally to prevent deallocation
|
||||
hostingController = newHostingController
|
||||
|
||||
let containerView = newHostingController.view!
|
||||
@ -50,7 +49,7 @@ func waitForController() {
|
||||
SDL_SetWindowPosition(sdlWindow, 0, 0)
|
||||
}
|
||||
|
||||
timer.invalidate() // Stop the timer after adding the view
|
||||
timer.invalidate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -134,12 +134,13 @@ class Ryujinx {
|
||||
|
||||
isRunning = true
|
||||
|
||||
RunLoop.current.perform {
|
||||
let url = URL(string: config.gamepath)!
|
||||
MainThread {
|
||||
|
||||
let url = URL(string: config.gamepath)
|
||||
|
||||
do {
|
||||
let args = self.buildCommandLineArgs(from: config)
|
||||
let accessing = url.startAccessingSecurityScopedResource()
|
||||
let accessing = url?.startAccessingSecurityScopedResource()
|
||||
|
||||
// Convert Arguments to ones that Ryujinx can Read
|
||||
let cArgs = args.map { strdup($0) }
|
||||
@ -151,8 +152,8 @@ class Ryujinx {
|
||||
|
||||
if result != 0 {
|
||||
self.isRunning = false
|
||||
if accessing {
|
||||
url.stopAccessingSecurityScopedResource()
|
||||
if let accessing, accessing {
|
||||
url!.stopAccessingSecurityScopedResource()
|
||||
}
|
||||
|
||||
throw RyujinxError.executionError(code: result)
|
||||
@ -177,6 +178,19 @@ class Ryujinx {
|
||||
return isRunning
|
||||
}
|
||||
|
||||
|
||||
func MainThread(_ block: @escaping @Sendable () -> Void) {
|
||||
if #available(iOS 17.0, *) {
|
||||
RunLoop.current.perform {
|
||||
block()
|
||||
}
|
||||
} else {
|
||||
DispatchQueue.main.async {
|
||||
block()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func buildCommandLineArgs(from config: Configuration) -> [String] {
|
||||
var args: [String] = []
|
||||
|
||||
|
@ -22,6 +22,51 @@ public struct Game: Identifiable, Equatable {
|
||||
var version: String
|
||||
var icon: UIImage?
|
||||
|
||||
|
||||
static func convertGameInfoToGame(gameInfo: GameInfo, url: URL) -> Game {
|
||||
var gameInfo = gameInfo
|
||||
var gameTemp = Game(containerFolder: url.deletingLastPathComponent(), fileType: .item, fileURL: url, titleName: "", titleId: "", developer: "", version: "")
|
||||
|
||||
gameTemp.titleName = withUnsafePointer(to: &gameInfo.TitleName) {
|
||||
$0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: $0)) {
|
||||
String(cString: $0)
|
||||
}
|
||||
}
|
||||
|
||||
gameTemp.developer = withUnsafePointer(to: &gameInfo.Developer) {
|
||||
$0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: $0)) {
|
||||
String(cString: $0)
|
||||
}
|
||||
}
|
||||
|
||||
gameTemp.titleId = withUnsafePointer(to: &gameInfo.TitleId) {
|
||||
$0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: $0)) {
|
||||
String(cString: $0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gameTemp.version = withUnsafePointer(to: &gameInfo.Version) {
|
||||
$0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: $0)) {
|
||||
String(cString: $0)
|
||||
}
|
||||
}
|
||||
|
||||
let imageSize = Int(gameInfo.ImageSize)
|
||||
if imageSize > 0, imageSize <= 1024 * 1024 {
|
||||
let imageData = Data(bytes: gameInfo.ImageData, count: imageSize)
|
||||
|
||||
gameTemp.icon = UIImage(data: imageData)
|
||||
} else {
|
||||
print("Invalid image size.")
|
||||
|
||||
}
|
||||
|
||||
|
||||
return gameTemp
|
||||
|
||||
}
|
||||
|
||||
func createImage(from gameInfo: GameInfo) -> UIImage? {
|
||||
// Access the struct
|
||||
let gameInfoValue = gameInfo
|
||||
|
@ -52,6 +52,9 @@ struct ContentView: View {
|
||||
// MoltenVKSettings(string: "MVK_CONFIG_PREFILL_METAL_COMMAND_BUFFERS", value: "2"),
|
||||
MoltenVKSettings(string: "MVK_USE_METAL_PRIVATE_API", value: "0"),
|
||||
// MoltenVKSettings(string: "MVK_CONFIG_RESUME_LOST_DEVICE", value: "1"),
|
||||
MoltenVKSettings(string: "MVK_CONFIG_MAX_ACTIVE_METAL_COMMAND_BUFFERS_PER_QUEUE", value: "192"),
|
||||
MoltenVKSettings(string: "MVK_CONFIG_PREFILL_METAL_COMMAND_BUFFERS", value: "2"),
|
||||
//MVK_CONFIG_LOG_LEVEL
|
||||
MoltenVKSettings(string: "MVK_CONFIG_USE_METAL_PRIVATE_API", value: "0")
|
||||
]
|
||||
|
||||
@ -285,12 +288,6 @@ struct ContentView: View {
|
||||
config.gamepath = game.fileURL.path
|
||||
config.inputids = Array(Set(currentControllers.map(\.id)))
|
||||
|
||||
if mVKPreFillBuffer {
|
||||
let setting = MoltenVKSettings(string: "MVK_CONFIG_PREFILL_METAL_COMMAND_BUFFERS", value: "1")
|
||||
setenv(setting.string, setting.value, 1)
|
||||
print("Prefill Metal Command Buffer Enabled")
|
||||
}
|
||||
|
||||
|
||||
if config.inputids.isEmpty {
|
||||
config.inputids.append("0")
|
||||
|
@ -223,29 +223,7 @@ struct GameLibraryView: View {
|
||||
|
||||
var gameInfo = get_game_info(handle.fileDescriptor, extensionPtr)
|
||||
|
||||
var game = Game(containerFolder: url.deletingLastPathComponent(), fileType: .item, fileURL: url, titleName: "", titleId: "", developer: "", version: "")
|
||||
|
||||
game.titleName = withUnsafePointer(to: &gameInfo.TitleName) {
|
||||
$0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: $0)) {
|
||||
String(cString: $0)
|
||||
}
|
||||
}
|
||||
|
||||
game.developer = withUnsafePointer(to: &gameInfo.Developer) {
|
||||
$0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: $0)) {
|
||||
String(cString: $0)
|
||||
}
|
||||
}
|
||||
|
||||
game.titleId = String(gameInfo.TitleId)
|
||||
|
||||
print(String(gameInfo.TitleId))
|
||||
|
||||
|
||||
game.version = String(gameInfo.Version)
|
||||
|
||||
game.icon = game.createImage(from: gameInfo)
|
||||
|
||||
let game = Game.convertGameInfoToGame(gameInfo: gameInfo, url: url)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
startemu = game
|
||||
@ -321,29 +299,10 @@ struct GameLibraryView: View {
|
||||
let fileExtension = (fileURLCandidate.pathExtension as NSString).utf8String
|
||||
let extensionPtr = UnsafeMutablePointer<CChar>(mutating: fileExtension)
|
||||
|
||||
var gameInfo = get_game_info(handle.fileDescriptor, extensionPtr)
|
||||
|
||||
var game = Game(containerFolder: romsDirectory, fileType: .item, fileURL: fileURLCandidate, titleName: "", titleId: "", developer: "", version: "")
|
||||
|
||||
game.titleName = withUnsafePointer(to: &gameInfo.TitleName) {
|
||||
$0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: $0)) {
|
||||
String(cString: $0)
|
||||
}
|
||||
}
|
||||
|
||||
game.developer = withUnsafePointer(to: &gameInfo.Developer) {
|
||||
$0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: $0)) {
|
||||
String(cString: $0)
|
||||
}
|
||||
}
|
||||
|
||||
game.titleId = String(gameInfo.TitleId)
|
||||
|
||||
|
||||
game.version = String(gameInfo.Version)
|
||||
|
||||
game.icon = game.createImage(from: gameInfo)
|
||||
let gameInfo = get_game_info(handle.fileDescriptor, extensionPtr)
|
||||
|
||||
let game = Game.convertGameInfoToGame(gameInfo: gameInfo, url: fileURLCandidate)
|
||||
|
||||
games.append(game)
|
||||
} catch {
|
||||
|
@ -374,9 +374,9 @@ struct SettingsView: View {
|
||||
Section {
|
||||
DisclosureGroup {
|
||||
|
||||
Toggle(isOn: $mVKPreFillBuffer) {
|
||||
labelWithIcon("MVK: Pre-Fill Metal Command Buffers", iconName: "gearshape")
|
||||
}.tint(.blue)
|
||||
// Toggle(isOn: $mVKPreFillBuffer) {
|
||||
// labelWithIcon("MVK: Pre-Fill Metal Command Buffers", iconName: "gearshape")
|
||||
// }.tint(.blue)
|
||||
|
||||
HStack {
|
||||
labelWithIcon("Page Size", iconName: "textformat.size")
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -580,6 +580,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
texture.Sampler = _dummySampler.GetSampler().Get(cbs).Value;
|
||||
}
|
||||
|
||||
if (OperatingSystem.IsIOS()) {
|
||||
Span<DescriptorImageInfo> singleTexture = textures.Slice(i, 1);
|
||||
dsc.UpdateImages(0, binding + i, singleTexture, DescriptorType.CombinedImageSampler);
|
||||
|
@ -23,7 +23,10 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||
|
||||
config.UseMetalArgumentBuffers = true;
|
||||
|
||||
if (OperatingSystem.IsIOSVersionAtLeast(17)) {
|
||||
config.SemaphoreSupportStyle = MVKVkSemaphoreSupportStyle.MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_SINGLE_QUEUE;
|
||||
}
|
||||
|
||||
config.SynchronousQueueSubmits = false;
|
||||
|
||||
config.ResumeLostDevice = true;
|
||||
|
@ -322,7 +322,14 @@ namespace Ryujinx.Headless.SDL2
|
||||
|
||||
var gameInfo = GetGameInfo(stream, extension);
|
||||
|
||||
return new GameInfoNative(gameInfo.FileSize, gameInfo.TitleName, gameInfo.TitleId, gameInfo.Developer, gameInfo.Version, gameInfo.Icon);
|
||||
return new GameInfoNative(
|
||||
(ulong)gameInfo.FileSize,
|
||||
gameInfo.TitleName,
|
||||
gameInfo.TitleId,
|
||||
gameInfo.Developer,
|
||||
gameInfo.Version,
|
||||
gameInfo.Icon
|
||||
);
|
||||
}
|
||||
|
||||
public static GameInfo? GetGameInfo(Stream gameStream, string extension)
|
||||
@ -1482,42 +1489,41 @@ namespace Ryujinx.Headless.SDL2
|
||||
{
|
||||
public ulong FileSize;
|
||||
public fixed byte TitleName[512];
|
||||
public ulong TitleId;
|
||||
public fixed byte TitleId[32];
|
||||
public fixed byte Developer[256];
|
||||
public uint Version;
|
||||
public fixed byte Version[16];
|
||||
public byte* ImageData;
|
||||
public uint ImageSize;
|
||||
|
||||
public GameInfoNative(ulong fileSize, string titleName, ulong titleId, string developer, uint version, byte[] imageData)
|
||||
public GameInfoNative(ulong fileSize, string titleName, string titleId, string developer, string version, byte[] imageData)
|
||||
{
|
||||
FileSize = fileSize;
|
||||
TitleId = titleId;
|
||||
Version = version;
|
||||
|
||||
fixed (byte* developerPtr = Developer)
|
||||
fixed (byte* titleNamePtr = TitleName)
|
||||
fixed (byte* titleIdPtr = TitleId)
|
||||
fixed (byte* developerPtr = Developer)
|
||||
fixed (byte* versionPtr = Version)
|
||||
{
|
||||
CopyStringToFixedArray(titleName, titleNamePtr, 512);
|
||||
CopyStringToFixedArray(titleId, titleIdPtr, 32);
|
||||
CopyStringToFixedArray(developer, developerPtr, 256);
|
||||
CopyStringToFixedArray(version, versionPtr, 16);
|
||||
}
|
||||
|
||||
if (imageData == null || imageData.Length > 4096 * 4096)
|
||||
{
|
||||
// throw new ArgumentException("Image data must not exceed 4 MB.");
|
||||
ImageSize = (uint)0;
|
||||
ImageSize = 0;
|
||||
ImageData = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
ImageSize = (uint)imageData.Length;
|
||||
|
||||
ImageData = (byte*)Marshal.AllocHGlobal(imageData.Length);
|
||||
|
||||
Marshal.Copy(imageData, 0, (IntPtr)ImageData, imageData.Length);
|
||||
}
|
||||
}
|
||||
|
||||
// Don't forget to free the allocated memory
|
||||
// Free allocated memory for ImageData
|
||||
public void Dispose()
|
||||
{
|
||||
if (ImageData != null)
|
||||
@ -1526,17 +1532,14 @@ namespace Ryujinx.Headless.SDL2
|
||||
ImageData = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void CopyStringToFixedArray(string source, byte* destination, int length)
|
||||
{
|
||||
var span = new Span<byte>(destination, length);
|
||||
span.Clear();
|
||||
Encoding.UTF8.GetBytes(source, span);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CopyArrayToFixedArray(byte[] source, byte* destination, int maxLength)
|
||||
{
|
||||
var span = new Span<byte>(destination, maxLength);
|
||||
source.AsSpan().CopyTo(span);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user