Compare commits

..

3 Commits

Author SHA1 Message Date
ParantezTech ddfda7e220 [log] log to file for CLI and fix some issues 2026-07-13 14:30:30 +03:00
ParantezTech af106d4b38 reuse 2026-07-13 14:11:22 +03:00
ParantezTech 1dafc306b5 [emulator] Fix mitigated child process handling 2026-07-13 14:06:31 +03:00
4 changed files with 9 additions and 69 deletions
@@ -83,6 +83,7 @@ public sealed class SharpEmuRuntime : ISharpEmuRuntime
ImportTraceLimit = Math.Max(0, options.ImportTraceLimit), ImportTraceLimit = Math.Max(0, options.ImportTraceLimit),
}; };
var moduleManager = new ModuleManager(); var moduleManager = new ModuleManager();
moduleManager.RegisterFromAssembly(typeof(VideoOutExports).Assembly, Generation.Gen4 | Generation.Gen5, Aerolib.Instance);
moduleManager.RegisterFromAssembly(typeof(KernelExports).Assembly, Generation.Gen4 | Generation.Gen5, Aerolib.Instance); moduleManager.RegisterFromAssembly(typeof(KernelExports).Assembly, Generation.Gen4 | Generation.Gen5, Aerolib.Instance);
moduleManager.Freeze(); moduleManager.Freeze();
@@ -718,7 +718,7 @@ internal static class Gen5ShaderTranslator
} }
var src0 = word & 0x1FF; var src0 = word & 0x1FF;
sizeDwords = opcode is 0x20 or 0x21 or 0x2C or 0x2D || src0 is 0xF9 or 0xFA or 0xFF ? 2u : 1u; sizeDwords = opcode is 0x20 or 0x21 || src0 is 0xF9 or 0xFA or 0xFF ? 2u : 1u;
error = string.Empty; error = string.Empty;
name = opcode switch name = opcode switch
{ {
@@ -757,9 +757,7 @@ internal static class Gen5ShaderTranslator
0x28 => "VAddcU32", 0x28 => "VAddcU32",
0x29 => "VSubbU32", 0x29 => "VSubbU32",
0x2A => "VSubbrevU32", 0x2A => "VSubbrevU32",
0x2B => "VFmacF32", 0x2B => "VLdexpF32",
0x2C => "VFmamkF32",
0x2D => "VFmaakF32",
0x2F => "VCvtPkrtzF16F32", 0x2F => "VCvtPkrtzF16F32",
0x30 => "VCvtPkU16U32", 0x30 => "VCvtPkU16U32",
0x31 => "VCvtPkI16I32", 0x31 => "VCvtPkI16I32",
@@ -872,7 +870,6 @@ internal static class Gen5ShaderTranslator
0x10F => "VMinF32", 0x10F => "VMinF32",
0x110 => "VMaxF32", 0x110 => "VMaxF32",
0x11F => "VMacF32", 0x11F => "VMacF32",
0x12B => "VFmacF32",
0x12F => "VCvtPkrtzF16F32", 0x12F => "VCvtPkrtzF16F32",
0x141 => "VMadF32", 0x141 => "VMadF32",
0x143 => "VMadU32U24", 0x143 => "VMadU32U24",
@@ -1382,7 +1379,7 @@ internal static class Gen5ShaderTranslator
Gen5Operand.Source(word & 0x1FF, literal), Gen5Operand.Source(word & 0x1FF, literal),
Gen5Operand.Vector((word >> 9) & 0xFF), Gen5Operand.Vector((word >> 9) & 0xFF),
]; ];
if (opcode is "VMadMkF32" or "VFmamkF32" && literal.HasValue) if (opcode == "VMadMkF32" && literal.HasValue)
{ {
sources = sources =
[ [
@@ -1391,7 +1388,7 @@ internal static class Gen5ShaderTranslator
sources[1], sources[1],
]; ];
} }
else if (opcode is "VMadAkF32" or "VFmaakF32" && literal.HasValue) else if (opcode == "VMadAkF32" && literal.HasValue)
{ {
sources = sources =
[ [
@@ -255,8 +255,6 @@ internal static partial class Gen5SpirvTranslator
case "VFmaF32": case "VFmaF32":
case "VMadMkF32": case "VMadMkF32":
case "VMadAkF32": case "VMadAkF32":
case "VFmamkF32":
case "VFmaakF32":
result = EmitFloatResult( result = EmitFloatResult(
instruction, instruction,
Ext( Ext(
@@ -267,7 +265,6 @@ internal static partial class Gen5SpirvTranslator
GetFloatSource(instruction, 2))); GetFloatSource(instruction, 2)));
break; break;
case "VMacF32": case "VMacF32":
case "VFmacF32":
{ {
var addend = Bitcast(_floatType, LoadV(destination)); var addend = Bitcast(_floatType, LoadV(destination));
result = EmitFloatResult( result = EmitFloatResult(
@@ -178,7 +178,6 @@ internal static unsafe class VulkanVideoPresenter
private static uint _windowHeight; private static uint _windowHeight;
private static bool _closed; private static bool _closed;
private const string DebugUtilsExtensionName = "VK_EXT_debug_utils"; private const string DebugUtilsExtensionName = "VK_EXT_debug_utils";
private const uint NvidiaVendorId = 0x10DE;
private static bool _splashHidden; private static bool _splashHidden;
private static long _enqueuedGuestWorkSequence; private static long _enqueuedGuestWorkSequence;
private static long _completedGuestWorkSequence; private static long _completedGuestWorkSequence;
@@ -1503,13 +1502,6 @@ internal static unsafe class VulkanVideoPresenter
Check(_vk.EnumeratePhysicalDevices(_instance, &deviceCount, devicePointer), "vkEnumeratePhysicalDevices"); Check(_vk.EnumeratePhysicalDevices(_instance, &deviceCount, devicePointer), "vkEnumeratePhysicalDevices");
} }
// Hybrid laptops enumerate the iGPU first, and AMD's integrated driver
// segfaults compiling some translated shaders, so rank rather than take
// the first hit. SHARPEMU_VK_DEVICE=<substring> pins an adapter by name.
var deviceOverride = Environment.GetEnvironmentVariable("SHARPEMU_VK_DEVICE");
var bestScore = int.MinValue;
var found = false;
foreach (var device in devices) foreach (var device in devices)
{ {
uint queueCount = 0; uint queueCount = 0;
@@ -1529,62 +1521,15 @@ internal static unsafe class VulkanVideoPresenter
continue; continue;
} }
_vk.GetPhysicalDeviceProperties(device, out var properties);
var name = SilkMarshal.PtrToString((nint)properties.DeviceName) ?? string.Empty;
var score = ScorePhysicalDevice(properties, name, deviceOverride);
Console.Error.WriteLine(
$"[LOADER][INFO] Vulkan candidate: {name} ({properties.DeviceType}) score={score}");
if (score > bestScore)
{
bestScore = score;
_physicalDevice = device; _physicalDevice = device;
_queueFamilyIndex = index; _queueFamilyIndex = index;
found = true; return;
}
break;
} }
} }
if (!found)
{
throw new InvalidOperationException("No Vulkan graphics/present queue was found."); throw new InvalidOperationException("No Vulkan graphics/present queue was found.");
} }
_vk.GetPhysicalDeviceProperties(_physicalDevice, out var selected);
Console.Error.WriteLine(
$"[LOADER][INFO] Vulkan device: {SilkMarshal.PtrToString((nint)selected.DeviceName)} ({selected.DeviceType})");
}
private static int ScorePhysicalDevice(
PhysicalDeviceProperties properties,
string name,
string? deviceOverride)
{
if (!string.IsNullOrWhiteSpace(deviceOverride))
{
return name.Contains(deviceOverride, StringComparison.OrdinalIgnoreCase) ? 1000 : -1000;
}
var score = properties.DeviceType switch
{
PhysicalDeviceType.DiscreteGpu => 300,
PhysicalDeviceType.VirtualGpu => 100,
PhysicalDeviceType.Cpu => 50,
// Last resort: only picked when nothing else can present.
PhysicalDeviceType.IntegratedGpu => -100,
_ => 10,
};
if (properties.VendorID == NvidiaVendorId)
{
score += 500;
}
return score;
}
private void CreateDevice() private void CreateDevice()
{ {
var priority = 1.0f; var priority = 1.0f;