Я у нас есть репозиторий, над которым ведется работа.
Проблема
При случайном FSR (например. amd_fidelityfx_dx12.dll), загрузите его в приложение C# и вызовите метод ffxQuery.
Библиотеки DLL можно получить либо при запуске кода из вышеуказанного репозитория, либо они также включены в SDK AMD FidelityFX.
Упомянутый выше ffqQuery взят из образцов, предоставленных AMD здесь и здесь. Однако этот код написан на C++, мне нужно сделать то же самое, что и на C#.
Моя текущая попытка
Моя текущая попытка попытка находится в моем репозитории ReadFSRVersionFromCSharp. Сначала я не мог ничего загрузить. Немного поспав и с помощью GitHub Copilot/GPT-4o выдал код, который наполовину работает.
Я не C++-разработчик, у меня нет знаний по правильной загрузке C++-dll. в С#. Если ИИ дал мне ужасный код, укажите, как я могу его улучшить.
В файле AMDFidelityFXAPI.cs мне удалось заставить его динамически загружать DLL. используя методы из kernel32.dll
Код: Выделить всё
// 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);
Код: Выделить всё
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);
Код: Выделить всё
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}");
Оставшаяся проблемаВторая половина кода, предоставленного AMD, должна загрузить версию и идентификаторы FSR.
Код: Выделить всё
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);
Код: Выделить всё
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);
}
Если я запущу это как в библиотеках DX12, так и в Vulkan, я получу следующий результат:
Код: Выделить всё
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
Код: Выделить всё
ID: 7, Name: 3.1.3
Используйте только идентификаторы версий, возвращаемые ffxQuery, в ffxQueryDescGetVersions с соответствующим типом структуры создания
из этого я предполагаю, что идентификаторы, возвращаемые для строк 3.1.3 и 2.3.2, должны отличаться, поскольку они используются при создании контекста FSR относительно того, какую версию использовать.
Подробнее здесь: https://stackoverflow.com/questions/793 ... ll-support