I Ich habe hier ein Repository, in dem daran gearbeitet wird.
Das Problem
Bei einem zufälligen FSR (z. B. amd_fidelityfx_dx12.dll), laden Sie es in eine C#-Anwendung und rufen Sie die ffxQuery-Methode auf.
Die DLLs können entweder beim Ausführen von Code aus dem oben genannten Repository abgerufen werden, oder Sie sind auch im AMD FidelityFX SDK enthalten.
Die oben erwähnte ffqQuery stammt aus den von AMD hier und hier bereitgestellten Beispielen. Obwohl dieser Code C++ ist, muss ich die gleichen Dinge von C# aus tun.
Mein aktueller Versuch
Mein aktueller Der Versuch befindet sich in meinem ReadFSRVersionFromCSharp-Repository. Anfangs konnte ich nichts laden. Nach etwas Schlaf und mit Hilfe von GitHub Copilot/GPT-4o spuckte es Code aus, der halb funktioniert.
Ich bin kein C++-Entwickler, ich habe keine Kenntnisse im korrekten Laden von C++-DLLs in C#. Wenn mir die KI schrecklichen Code gegeben hat, zeigen Sie mir bitte, wie ich ihn verbessern kann.
In der Datei AMDFidelityFXAPI.cs habe ich es geschafft, dass die DLL dynamisch geladen wird Verwenden von Methoden aus kernel32.dll
Code: Select all
// Define the LoadLibrary and GetProcAddress functions
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool FreeLibrary(IntPtr hModule);
Code: Select all
ffx::QueryDescGetVersions versionQuery{};
versionQuery.createDescType = FFX_API_CREATE_CONTEXT_DESC_TYPE_UPSCALE;
versionQuery.device = GetDX12Device(); // only for DirectX 12 applications
uint64_t versionCount = 0;
versionQuery.outputCount = &versionCount;
// get number of versions for allocation
ffxQuery(nullptr, &versionQuery.header);
Code: Select all
var versionQuery = new QueryDescGetVersions();
//versionQuery.createDescType = FFX_API_CREATE_CONTEXT_DESC_TYPE_UPSCALE;
versionQuery.createDescType = FxxConsts.FFX_API_CREATE_CONTEXT_DESC_TYPE_UPSCALE;
// versionQuery.device = GetDX12Device(); // only for DirectX 12 applications
versionQuery.device = IntPtr.Zero;
// uint64_t versionCount = 0;
UInt64 versionCount = 0;
versionQuery.outputCount = Marshal.AllocHGlobal(sizeof(UInt64));
Marshal.WriteInt64(versionQuery.outputCount, (UInt32)versionCount);
Debug.WriteLine("AMDFidelityFXAPI - Reading version count");
// get number of versions for allocation
// ffxQuery(IntPtr.Zero, &versionQuery.header);
var returnCode = ffxQuery(IntPtr.Zero, ref versionQuery);
Debug.WriteLine($"AMDFidelityFXAPI - returnCode: {returnCode}");
versionCount = (UInt64)Marshal.ReadInt64(versionQuery.outputCount);
Debug.WriteLine($"AMDFidelityFXAPI - versionCount: {versionCount}");
Das verbleibende ProblemDie zweite Hälfte des von AMD bereitgestellten Codes sollte die FSR-Version und -IDs laden.
Code: Select all
std::vector versionNames;
std::vector versionIds;
m_FsrVersionIds.resize(versionCount);
versionNames.resize(versionCount);
versionQuery.versionIds = versionIds.data();
versionQuery.versionNames = versionNames.data();
// fill version ids and names arrays.
ffxQuery(nullptr, &versionQuery.header);
Code: Select all
var versionCountInt = (int)versionCount;
//std::vector versionNames;
//std::vector versionIds;
//m_FsrVersionIds.resize(versionCount);
//versionNames.resize(versionCount);
var versionNames = new List(versionCountInt);
var versionIds = new List(versionCountInt);
var versionNamesPtrs = new IntPtr[versionCountInt];
var versionIdsPtrs = new IntPtr[versionCountInt];
try
{
for (var i = 0; i < versionCountInt; i++)
{
versionNames.Add(null);
versionIds.Add(0);
}
//versionQuery.versionIds = versionIds.data();
//versionQuery.versionNames = versionNames.data();
versionQuery.versionIds = Marshal.AllocHGlobal(sizeof(UInt64) * versionCountInt);
versionQuery.versionNames = Marshal.AllocHGlobal(IntPtr.Size * versionCountInt);
for (var i = 0; i < versionCountInt; i++)
{
versionIdsPtrs[i] = Marshal.AllocHGlobal(sizeof(UInt64));
Marshal.WriteInt64(versionIdsPtrs[i], (long)versionIds[i]);
Marshal.WriteIntPtr(versionQuery.versionIds, i * IntPtr.Size, versionIdsPtrs[i]);
versionNamesPtrs[i] = Marshal.StringToHGlobalAnsi(versionNames[i]);
Marshal.WriteIntPtr(versionQuery.versionNames, i * IntPtr.Size, versionNamesPtrs[i]);
}
// fill version ids and names arrays.
//ffxQuery(nullptr, &versionQuery.header);
returnCode = ffxQuery(IntPtr.Zero, ref versionQuery);
Debug.WriteLine($"AMDFidelityFXAPI - returnCode: {returnCode}");
if (returnCode != FfxApiReturnCodes.FFX_API_RETURN_OK)
{
throw new Exception($"Failed to get version count. Return code: {returnCode}");
}
for (var i = 0; i < versionCountInt; i++)
{
versionIds[i] = (UInt64)Marshal.ReadInt64(versionIdsPtrs[i]);
versionNames[i] = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(versionQuery.versionNames, i * IntPtr.Size));
}
Console.WriteLine("AMDFidelityFXAPI - Version Names and IDs:");
for (var i = 0; i < versionCountInt; i++)
{
Console.WriteLine($"ID: {versionIds[i]}, Name: {versionNames[i]}");
}
return versionNames;
}
finally
{
foreach (var ptr in versionIdsPtrs)
{
Marshal.FreeHGlobal(ptr);
}
foreach (var ptr in versionNamesPtrs)
{
Marshal.FreeHGlobal(ptr);
}
Marshal.FreeHGlobal(versionQuery.versionIds);
Marshal.FreeHGlobal(versionQuery.versionNames);
}
Wenn ich dies sowohl auf der DX12- als auch auf der Vulkan-DLL ausführe, erhalte ich die folgende Ausgabe:
Code: Select all
AMDFidelityFXAPI - Loading amd_fidelityfx_vk.dll
AMDFidelityFXAPI - Reading version count
AMDFidelityFXAPI - returnCode: FFX_API_RETURN_OK
AMDFidelityFXAPI - versionCount: 2
AMDFidelityFXAPI - returnCode: FFX_API_RETURN_OK
AMDFidelityFXAPI - Version Names and IDs:
ID: 0, Name: 3.1.3
ID: 0, Name: 2.3.2
AMDFidelityFXAPI - Loading amd_fidelityfx_dx12.dll
AMDFidelityFXAPI - Reading version count
AMDFidelityFXAPI - returnCode: FFX_API_RETURN_OK
AMDFidelityFXAPI - versionCount: 2
AMDFidelityFXAPI - returnCode: FFX_API_RETURN_OK
AMDFidelityFXAPI - Version Names and IDs:
ID: 0, Name: 3.1.3
ID: 0, Name: 2.3.2
Code: Select all
ID: 7, Name: 3.1.3
Nur von ffxQuery zurückgegebene Versions-IDs in ffxQueryDescGetVersions mit dem entsprechenden Erstellungsstrukturtyp verwenden
Daher gehe ich davon aus, dass die für die Zeilen 3.1.3 und 2.3.2 zurückgegebenen IDs unterschiedlich sein sollten, da diese beim Erstellen des FSR-Kontexts für die zu verwendende Version verwendet werden.